My fantasy: instant array of AR attributes?

If there’s a way to do this, I would be very happy:

let’s pretend that I have an array called folks holding several AR
objects from a model called People:

folks = [ <AR 1: name => “bob”, sex => “m”, age => 40>,
<AR 2: name => “sam”, sex => “m”, age => 7>,
<AR 3: name => “dee”, sex => “f”, age => 25> ]

What i’ve always wanted to do was say something like:

folks.names

…and get an array back with [“bob”,“sam”,“dee”].

It seems kind of cumbersome to write a loop to do this, especially
when RoR is supposed to be all neato and cool. Am I missing something
obvious or do I really have to use a loop?

Thanks!


Jason F. - [email protected] - http://www.seethroo.us/
work: (310) 601-8454
cell: (415) 254-4890
AIM/Skype: jfrankov

You could go about it a number of ways.

I like this method

folks.collect! { |person| person.name}

Now folks is an array of all of their names…

On 12/22/06, Jason F. [email protected] wrote:


seth at subimage interactive
http://www.subimage.com/sublog/

subimage interactive wrote:

You could go about it a number of ways.

I like this method

folks.collect! { |person| person.name}

Doesn’t Rails provide a shortcut:

folks.collect(&:name)

?


Phlip
Redirecting... ← NOT a blog!!!

Hi –

On Fri, 22 Dec 2006, Phlip wrote:

folks.collect(&:name)

?

Yes, and actually the thing that makes it work (Symbol#to_proc) is in
1.9:

$ /usr/local/lib/ruby-cvs/bin/ruby -ve ‘puts [1,2,3].map(&:to_f)’
ruby 1.9.0 (2006-12-09 patchlevel 0) [i686-linux]
1.0
2.0
3.0

David


Q. What’s a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (Ruby for Rails)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Even shorter:

names = folks.collect(&:name)

-christos

I love it! My fantasy has come true. Anyone got a handle on what the
& does? I knew about collect but it alters the original array, which
I want to avoid (shuold’ve said that in my first email, sorry).

Thanks to everyone for the suggestions!

-Jason


Jason F. - [email protected]
work: (310) 601-8454
cell: (415) 254-4890
AIM/Skype: jfrankov

Hi –

On Fri, 22 Dec 2006, Jason F. wrote:

On Dec 22, 2006, at 5:27 PM, Christos Z. wrote:

Even shorter:

names = folks.collect(&:name)

I love it! My fantasy has come true. Anyone got a handle on what the & does?
I knew about collect but it alters the original array, which I want to avoid
(shuold’ve said that in my first email, sorry).

collect (aka map) doesn’t alter the original array, unless you use the
! version (collect! or map!). I think one of the people who replied
did use that, but Christos’s version doesn’t.

The & introduces a lambda (an anonymous function, technically an
instance of Proc), to be used as the code block to go with the method
call. For example, look at this:

array = [1,2,3,4,5]
array.map {|e| e * 10 } # [10,20,30,40,50]

and now with a separate lambda:

lam = lambda {|e| e * 10 }
array.map &lam # [10,20,30,40,50]

The reason it works with &:name is that Rails has a to_proc conversion
method for symbols. That method gets called automatically when the &
is applied. When you do &:name, you get a lambda that, if you wrote
it out by hand, would look like this:

lambda {|e| e.send(:name) }

So – the net effect of all of this is that this:

folks.collect(&:name)

calls collect on folks, with a code block (a lambda) that performs the
function of calling the “name” method on each element in folks. The
result is a second, result array, consisting of all the names.

David


Q. What’s a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (Ruby for Rails)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)