From: Jano Svitok Date: 2007-11-21T02:16:51+09:00 Subject: Re: Quick way to get attributes (without using collect) On Nov 20, 2007 6:03 PM, Max Williams wrote: > This was inspired by Rails, but i think it's common Ruby question. Say > i have an array of Employee objects, which have an attribute "name". I > want to get all the names, as an array. > > Let's say i already have the variable "employees", which points to an > array of Employee objects. > > What i want to do is something like this - > > employee_names = employees.names > > But what i have to keep on doing is something like this - > > employee_names = employees.collect{ |emp| emp.name} > > Now, this isn't a *massive* hassle, and i find Array#collect incredibly > useful, but it's a bit annoying to have to keep typing it again and > again. Is there a way to set it up so that > > .foos > > is automatically treated as > > .collect { |x| x.foo } > > ? > > Or another way to do this simply? Let me introduce to you #method_missing. It's being called when the method called is not found. The standard implementation just raises NoMethodError, but you can do anything there. In fact, this is how Rails does it's find_by_this_and_that magic. So, this is the idea (not tested, just written in the mail): class Array def method_missing(name, *args) single_method = name.to_s.chop # 1. name is a symbol, 2. chop for simplicity if !empty? && first.respond_to?(single_method) collect { |x| x.send(single_method, *args) } # do whatever you want here else super # inherited implementation end end end Just make sure that this will not break the whole system (check for 's', and look any methods that might end with it, etc.) Lookup the code in the Rails' sources, most probably you'll find there nice singular/plural conversion etc.