Passing arguments to Item Renderers

November 27th, 2008

When trying to create general-purpose item renderers in Flex, one of the first things I ran into was passing arguments. Passing arguments allows you to use the same item renderer in different ways.

The best solution I’ve been able to come up with is to create my own factory class:

package com.zacharypinter.util
{
	import flash.utils.Dictionary;
 
	import mx.core.IFactory;
 
	public class ArgumentsToRendererFactory implements IFactory
	{
		private var klass:Class;
		private var args:*;
 
		public function ArgumentsToRendererFactory(args:*,klass:Class) {
			this.args=args;
			this.klass=klass;
		}
 
		public function newInstance():*
		{
			var instance:Object = new klass;
 
 
			for (var key:String in args) {
				if (instance.hasOwnProperty(key)) {
					instance[key] = args[key];
				}
			}
 
			return instance;	
		}
 
	}
}

To use it, you can write something like this:

   <mx:List 
      width="100%" height="100%" 
      dataProvider="{users}" 
      selectable="false" 
      itemRenderer="{new ArgumentsToRendererFactory({group:this.radioGroup},UserRenderer)}" 
   />

In the above example, I’m using the ArgumentsToRendererFactory to pass a radio group to every item renderer. This lets me use radio buttons inside a list component.

Everyday Ruby Scripting - Renaming Files

August 20th, 2008

I recently had the need to replace around 50 files. However, the new files did not have the same name as the old files.

The old files had names like:

AD5001.indd
AD5002.indd
AD5003.indd

and the new files had names like:

AD5001_rev.indd
AD5002_rev.indd
AD5003_rev.indd

The solution was a quick ruby script:

require 'fileutils'
rev_files = Dir.glob("./**/*_rev*.indd")
 
rev_files.each do |rf|
  orig_file = rf.gsub("_rev","")
  FileUtils.rm(orig_file)
  FileUtils.mv(rf,orig_file)
  puts "Replaced #{orig_file} with #{rf}"
end

Originally, I was going to use some combination of Emacs and find-dired, but ultimately this proved simpler.

301 Redirects in Rails

July 25th, 2008

If you’ve ever searched for how to do a 301 redirect in Rails, you’ve probably seen this code:

headers["Status"] = "301 Moved Permanently"
redirect_to "http://www.domain.com/"

However, after doing some testing (thanks rspec!), I found that the above snippet does not work. Instead, it sends a 302 temporary redirect, which, of course, has an entirely different meaning for the search engines visiting your site.

Apparently, somewhere along the way, Rails stopped honoring the explicit Status header when using redirect_to. To achieve the correct result, you must now use:

head :moved_permanently, :location => "http://www.domain.com/"

To make things nicer, I added the following function to my application.rb file:

  def perm_redirect_to(options)
    url = case options
            when String
            options
            else
            url_for(options)
            end
    head :moved_permanently, :location => url
  end

Weak References with Dictionaries in Actionscript

October 11th, 2007

Actionscript dictionaries are a great tool for dealing with memory management because you can use them to create weak references to objects. This means that the object automatically goes away upon garbage collection if the only reference to it is in the Dictinary.

To use a dictionary in this manner, simply pass true to the constructor. However, one should note that this *only* makes the keys of the Dictionary weak.

For example:

class MyObject {
  public var message:String;
}
 
var dict:Dictionary = new Dictionary(true);
var obj1:MyObject = new MyObject();
obj1.message = "My really long message...";
var obj2:MyObject = new MyObject();
obj2.message = "My second really long message...";
 
dict[obj1] = true; //obj1 is weakly referenced
dict[2] = obj2; //obj2 is strongly referenced

If the only reference to an object is the *key* of a weakly referenced dictionary, the object will not persist after garbage collection. However, if the only reference to an object is the *value* of a key in a weakly referenced dictionary, the reference is considered strong and will force the object to persist after garbage collection.

So, what do you do if you want to store a dictionary of weakly referenced objects, but key them off of a meaningful value (such as an item id) rather than their reference id?

The answer is to use a simple WeakReference class ([source](http://www.bigroom.co.uk/blog/create-your-own-weak-references-in-actionscript-3)):

class WeakRef {
  private var dic:Dictionary;
 
  public function WeakRef( obj:* ) {
    dic = new Dictionary( true );
    dic[obj] = 1;
  }
 
  public function get():* {
    for( var item:* in dic ) {
      return item;
    }
    return null;
  }
}

From here, you can do the following:

var dict:Dictionary = new Dictionary(true);
var obj1:MyObject = new MyObject();
obj1.message = "My really long message...";
var obj2:MyObject = new MyObject();
obj2.message = "My second really long message...";
 
dict[1] = new WeakReference(obj1); //weakly referenced value
dict[2] = new WeakReference(obj2); //weakly referenced value

Now, you can key based off of a meaningful value, and still get all the benefits of weak references.

Actionscript Hash

October 9th, 2007

On the surface, the Dictionary object in Actionscript seems quite limited compared to the Hash and HashMap libraries of other languages. However, the functionality you would expect is still there, it’s just obscure.

For example, to loop through all keys in a Dictionary:

for (var key:Object in groupMap)
{
   trace(key + ", " + groupMap[key]);
}

To loop through all values in a Dictionary:

for each (var item:Object in groupMap)
{
   trace(item);
}

To check if a key exists (in a way that’s distinguishes from a key whose value could be null):

obj['key'] === undefined  //key exists

To remove a key/value pair from a Dictionary:

delete obj['key']

All of the above code will also work for a regular object treated like a hash.

eBay Desktop Launched

October 2nd, 2007

As I mentioned previously, I started working for effectiveUI in July. Since then, I’ve been working on Project Sandimas, the code name for the AIR application now known as eBay Desktop. The product launched into open beta yesterday and has already won an award at the Adobe MAX conference.

So go ahead and try it out!

ZFS on OS X?

April 30th, 2006

I just noticed a post on OSNews indicating that the OS X developers are interested in porting ZFS. This is great news! I’ve been using beta versions of Solaris at work and testing ZFS. It really is a remarkable file system and I can’t wait till I can get my five 250gb SATAs in a RAID-Z on OS X :)

What are Ruby Symbols?

December 12th, 2005

I’ve introduced a few friends/classmates/coworkers to Ruby and Rails lately, and many of them have since approached me and asked “what is that colon thing in ruby?” So, I’ve decided to explain Ruby symbols as I know them.


Symbols are essentially small, automatically created global read-only objects that have a unique numerical value associated with them and are accessed through the :[name] syntax. Any time you use a named symbol (such as :bob), you are really telling Ruby to find the object associated with the name “bob” in the global table of symbols. Therefore, :bob in one class returns exactly the same object that :bob returns in another class.



The numerical value associated with a symbol object is generated for you behind the scenes. You don’t really care what it is, you just care that it is unique among all other symbols.



This nature of symbol objects creates some very useful applications. For one, you can use a symbol as a named constant whose value you do not care about. For instance, you might have a C library with tons of interesting constants like

AR_REL_OP_GREATER_EQUAL = 3

For the sake of C programming, that constant has to have a value. However, if all you really care about is whether or not something is flagged as AR_REL_OP_GREATER_EQUAL, then the actual value is practically meaningless. In such a case with Ruby, you could use symbols to write code like

if x.operation == :greater_equal
   ...
end

You can check whether or not a value equals :greater_equal without ever having to select a numerical value for :greater_equal.
As an added bonus, you can call

:greater_equal.to_s

and get a full-blown String object out of the name of the Symbol. Now, that might not seem like a big deal just now, but think about converting AR_REL_OP_GREATER_EQUAL into a cstring. With symbols, it’s a piece of cake, and there are plenty of times when finding the actual name of a constant is useful, especially when it comes to debugging.



Since the actual object that is referenced by a symbol is global and unchangeable, it makes a perfect candidate for use as a key in a hash table. That is why you always see syntax such as

{:name=>"Zachary",:job=>"Programmer"}

The above code is short-hand syntax for creating a Hash object with the keys :name and :job mapped to the values “Zachary” and “Programmer”. Yes, one can always use String objects as keys in a Hash, but in Ruby, a String object is changeable (mutable). For example, you can call gsub! on a String and replace the contents of the object. Doing so would change the value that the String would hash to, and corrupt any Hash table that String was used as a key in.



If you’re a Java programmer, you should note this very important difference between a Ruby String and a Java String. In Java, String objects are unchangeable (immutable) and StringBuffers are changeable (mutable). In Ruby, Symbol objects are unchangeable and String objects are changeable. When you call concat (”+”) or replace on a Java String, you are actualy creating a brand new String object (instead of making changes to the current one). This is precisely why Java programmers are told to use a StringBuffer class instead of the “+” sign to concatenate several strings. In Ruby, no concern is paid to concatenation, since the core String class is mutable. Similarly, in Java, it is common to use a String object as a key in a HashMap. In Ruby, that’s frowned upon since a lot of things could go wrong if that String object were changed (as explained above).



Symbols may seem awkward at first because they are not common among other programming languages. However, there are many pro’s to the tradeoff made by choosing String/Symbol (Ruby) over StringBuffer/String (Java). Additionally, the unique nature of symbols has it’s own benefits when it comes to flags that were traditionally set with numerical constants.