24 Jan 2008

Code friendly hashes in Ruby with method_missing

I normally use Hashes for my test data. It is a very flexible way of setting up data. However, I want my tests to be as clear and simple as possible. Using hashes I need to write:


craig["username"].should be "craig"
craig["password"].should be "secret"


But I'd much rather write:

craig.username.should be "craig"
craig.password.should be "secret"


We can if we change the Ruby's Hash, so that the method_missing method uses the method name as the hash key:

class Hash
def method_missing(key)
self[key.to_s]
end
end


so now when we make some hashes:

address = {"street" => "29 Acacia Road",
"town" => "Nuttytown"}
contact = {"email" => "craig@facedowndog.com",
"tel" => "1800 454545"}
craig = {"username" => "craig",
"password" => "secret",
"address" => address,
"contact" => contact}

and use them like this:


puts craig.username # craig
puts craig.password # secret
puts craig.address.street # 29 Acacia Road
puts craig.contact.email # craig@facedowndog.com