This is a read-only archive!

RubyFacets

Today I found a really neat site, RubyFacets. Reminds me a bit of Perl's List::Util and List::MoreUtils; it's a bunch of methods to extend core classes in interesting ways.

A while back I posted about a way to prevent Ruby from raising an exception when trying to access an un-initialized subarray of a multidimensional array by extending NilClass. At RubyFacets I found something arguably more interesting: auto-initializing sub-hashes of a multi-dimensional hash.

The code:

def self.auto(*args)
  leet = lambda { |hsh, key| hsh[key] = new( &leet ) }
  new(*args,&leet)
end</pre>

It took me a couple minutes to figure out what this is doing. The standard new method for class Hash takes a block; if you reference an uninitialized hash element (via the [] method) that block will be called, which presumably assigns the element a default value (thought it doesn't have to).

The above method assigns a default value to any uninitialized Hash elements referenced via []. The default value is a new Hash object. The new Hash object's constructor is also passed a block which assigns new Hash objects to uninitialized Hash elements. You can see above that the "leet" anonymous function contains a reference to itself. I find that mighty clever. This lets you do crazy things like

h = Hash.auto
h['a']['lot']['of']['dimensions'] = true

and you'll get hashes the whole way down.

August 15, 2006 @ 7:45 AM PDT
Cateogory: Programming
Tags: Perl, Ruby, Lambda