[Ruby Skills] * and where

Posted by Tom on 2008-04-09

This is the first post in a new category I’ve added to the blog: “Ruby Skills”. It’s a place for me to share Ruby tricks and tips I’ve picked up along the way. Sometimes, as with this post, I’ll post about the Ruby extensions in HoboSupport. Now that HoboSupport is available as a gem, you can easily use these tricks in any Ruby project.

First up, two new Enumerable methods that HoboSupport adds: * and where. Attentive readers might be thinking – hang on, Array already defined *. Don’t worry, it still works.

* is some syntactic sugar for map. The idea is that we use ‘dot’ to call a method on one object, and we use ‘dot star’ to call a method on a whole collection of objects, returning all the results in a new array.

Say users is an array of user objects, and we want all the names:

users.*.name

Nice eh? You can pass arguments too:

users.*.to_json(:only => [:first_name, :surname])

Note that you can’t do

users.*.name.upcase

That would try to upcase the array. You’d have to do:

users.*.name.*.upcase # Not very efficient though

Of course, as a good functional programmer, I wouldn’t dream of giving map some love while neglecting filter (better known in Ruby-land as find_all or select). So you can also do:

users.where.active? # same as users.find_all {|u| u.active? }

There’s also where_not

Given that the result is just an array, we can chain them. Want the names of all the inactive users?

users.where_not.active?.*.name

Very handy in the console.



(edit)