Why Ruby is so sexy-awesome, part XXXIV

I use Ruby whenever I can. Not specifically with Rails – Rails extends the language and adds some nifty things, but the beauty is all Ruby’s.

Today I was using Ruby (in a Rails app, as it happens), and I had this “API” that returns generic hash data. I want to be able to take data from any source (Oracle, flat text, web service) and return data that’s in a very simple and easy-to-use format, so I chose to just convert data to a hash on a per-source basis.

But how do I handle typos in hash keys? What if somebody asks for “person[:name]” when they’re supposed to ask for “person[:full_name]“? They just get blank data and wonder WTF happened…. I can’t live with this situation, because it’s just too easy to forget a key’s name, or make a simple typo. I could return default data from the hash, such as “YOU FUCKED UP WITH YOUR KEY, SIRS”, but that could find its way into production and then I’m out a job.

So after a tiny bit of digging, I discovered that a Hash can not only have a default value, but also call a default block when a nonexistent key is requested:

irb(main):001:0> a = Hash.new {|hash, key| raise "#{key} not found!"}
=> {}
irb(main):005:0> a[1] = :foo
=> :foo
irb(main):006:0> a[1]
=> :foo
irb(main):007:0> a[2]
RuntimeError: 2 not found!
irb(main):008:0> a.default = nil
=> nil
irb(main):009:0> a[2]
=> nil

Normally I’m good with non-strict default data, but in this case it’s great to know I can actually validate data in a way that makes it hard to miss typos.

It’s not as safe as C++ (edge cases are only caught at runtime), but it’s far better than Perl (and nicer to read or write than both, IMO).

This entry was posted in Opinions, Programming, Ruby on Rails and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>