why does this work?
@users.select {|u| u.name == 'Bob'}
but this doesn't
@user.select(&:name == 'Bob')
Thanks.
why does this work?
@users.select {|u| u.name == 'Bob'}
but this doesn't
@user.select(&:name == 'Bob')
Thanks.
Because that evaluates as @user.select(&(:name == 'Bob')) ie @user.select &false and false doesn't have a to_proc method. The Symbol#to_proc is convenient shorthand but it's not a catch all.
Fred
Fred,
Thanks for the reply. I'm not sure I understand the response. By
that logic the following also evaluates to false but it seem to work.@user.select(&:active?)
Are you saying this syntax is impossible for what I'm trying to do?
The issue I have is that I already have this statement embedded in an
inject inside an HTML construct and it's to many {}
I thing you need to understand what's going on behind the scenes. You
could just write
@user.select {|u| u.active?} but that's a bit tedious
When you pass to a method an argument prefixed by & that tell ruby
'this is a proc and you should use this proc as the block for this
method. For example, this also words
p = lambda {|u| u.active?}
@user.select(&p)
Ruby being ruby, it doesn't really care if what you pass is actually a
proc, it just needs to look enough like one and will call to_proc on
such arguments.
What people have done is define Symbol#to_proc in such a way that it
creates a proc that does the right thing
If we were to limit ourselves to the case where the block takes a
single argument it's as simple as
def to_proc
Proc.new({|arg| arg.send(self)
end
It's a bit more complicated to cope with when the block is passed
multiple arguments
This fundamentally can't handle something like &:name == 'Bob', like I
said it ends up trying to call to_proc on false.
Fred