Hi all, I have been using a lot of Proc's and lambda's lately and I have
encountered something a little baffling. It might be syntax or a
misunderstanding of the language; would anyone mind helping me out?
I expect the following to print "Hello World", but it does not:
#!/usr/bin/env ruby
x = Proc.new { |a| p( block_given? ? yield(a) : a ) }
x.call( 'World' ) { |b| p "Hello #{b}" }
# Likewise, in continuation:
y = Proc.new { |b| p "Hello #{b}" }
p x.call( 'World', &y )
# this may be related, it returns false instead of nil... what gives?
p x.call( 'World' ) &y
__END__
I have nothing to offer but a thank you.
- travis
#!/usr/bin/env ruby
x = Proc.new { |a| p( block_given? ? yield(a) : a ) }
x.call( 'World' ) { |b| p "Hello #{b}" }
I don't believe you can pass a block argument when calling a Proc. It is silently ignored.
In your case the call to block_given? would be relative to the scope where Proc.new is called and not relative to the arguments passed when the block is executed via Proc#call. This is changing in Ruby 1.9 I believe so that block arguments can be provided to blocks when called via yield and/or Proc#call.
# Likewise, in continuation:
y = Proc.new { |b| p "Hello #{b}" }
p x.call( 'World', &y )
Same problem, a block argument is ignored by Proc#call.
# this may be related, it returns false instead of nil... what gives?
p x.call( 'World' ) &y
x.call('World') returns nil because the return value of the Proc is the last expression evaluated in the block which is a call to Kernel#p, which always returns nil.
So now you have:
p nil &y
which is getting parsed as a call to the bitwise and operator (nil & y), which returns false.
Gary Wright
···
On May 16, 2006, at 10:17 PM, travis michel wrote:
Is this any use to you?
x = Proc.new { |*a| a[1] ? a[1].call(a[0]) : a[0] }
p x.call( 'Boo' )
p x.call( 'World', Proc.new{ |b| "Hello #{b}" } )
"Boo"
"Hello World"
Regards,
Paul.
···
On 17/05/06, travis michel <meshac.ruby@gmail.com> wrote:
I expect the following to print "Hello World", but it does not:
#!/usr/bin/env ruby
x = Proc.new { |a| p( block_given? ? yield(a) : a ) }
x.call( 'World' ) { |b| p "Hello #{b}" }
Thank you very much Gary! /me crosses fingers for support in 1.9
travis michel wrote:
Thank you very much Gary! /me crosses fingers for support in 1.9
It's already there, I think.
Cheers,
Dave