Tuesday, March 15, 2011

More Readable Hash Member Access In Ruby

I've been doing a lot of work with the amazon-ec2 Ruby library for working with Amazon Web Services. I've also been using YAML a lot for config files. But both those systems return big nested hashes with string keys, so my code ends up looking like this: config['database']['security_group']

That gets tiresome to read. To fix that within these scripts, I extended the Hash object by adding an implementation of method_missing?, which Ruby calls when you try to execute a method on an object and it doesn't exist. My implementation says to try and use the method name as a key into the hash.



class Hash
def method_missing(method_name, *args, &block)
fetch(method_name.to_s,nil)
end
end



Now the same code from before looks like this: config.database.security_group. Ruby tries to call the "database" method of the config object (a Hash), fails, and then my extension to the class looks up a key named 'database' in the hash and returns that.

I find this much easier to read, particularly when it's repeated throughout the file. Of course, it assumes the keys in the hash are strings, but in this script they are (so my extension is only added for that script).