Collections with to_proc

why does this work?

@users.select {|u| u.name == ‘Bob’}

but this doesn’t

@user.select(&:name == ‘Bob’)

Thanks.

On 26 Mar 2008, at 08:37, Grayson P. wrote:

why does this work?

@users.select {|u| u.name == ‘Bob’}

but this doesn’t

@user.select(&:name == ‘Bob’)

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 {}

Thanks

GP

Frederick C. wrote:

On 26 Mar 2008, at 08:37, Grayson P. wrote:

why does this work?

@users.select {|u| u.name == ‘Bob’}

but this doesn’t

@user.select(&:name == ‘Bob’)

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

On 26 Mar 2008, at 17:02, Grayson P. wrote:

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs