Hi,
I searched in vain for the answer, but why doesn’t yield work inside
Ruby 192 blocks. The syntax allows you to pass the blocks as a &blk
param, but you have to call the block with blk.call. If you try to use
yield, you get a LocalJumpError:
ruby-1.9.2-p0 > l= lambda {|&blk| yield}
=> #<Proc:0x000001009d4ad0@(irb):2 (lambda)>
ruby-1.9.2-p0 > l.call {puts 1}
LocalJumpError: no block given (yield)
from (irb):2:in block in irb_binding' from (irb):3:in
call’
from (irb):3
from /Users/edh/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `’
But this works:
ruby-1.9.2-p0 > l= lambda {|&blk| blk.call}
=> #<Proc:0x000001009dc910@(irb):4 (lambda)>
ruby-1.9.2-p0 > l.call {puts 1}
1
=> nil
At least it agrees with block_given?
ruby-1.9.2-p0 > l=lambda {|&blk| puts “block given” if block_given?;
puts “done”}
=> #<Proc:0x00000101825f30@(irb):6 (lambda)>
ruby-1.9.2-p0 > l.call
done
=> nil
ruby-1.9.2-p0 > l.call {puts 1}
done
=> nil
I can live with block.call instead of yield, but no block_given?
Why would you want to pass a block to a block? Why not? so you can do
things like:
def meth(x, &block)
if block_given?
block.call(x) do |y|
puts "in meth " + y.to_s
end
end
end
ruby-1.9.2-p0 > meth(1) {|x, &blk| puts "in blok " + x.to_s; blk.call 2}
in blok 1
in meth 2
[Note, trying this with yield leads to a SyntaxError.]
Cheers,
Ed
Ed Howland
http://twitter.com/ed_howland
On Oct 22, 3:09pm, Ed Howland [email protected] wrote:
LocalJumpError: no block given (yield)
from (irb):2:in block in irb_binding' from (irb):3:in
call’
from (irb):3
from /Users/edh/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `’
irb(main):002:0> p = proc{|&blk| yield}
=> #Proc:0x02833540@:2(irb)
irb(main):003:0> p.call{puts 1}
LocalJumpError: no block given
from (irb):2
from (irb):3:in `call’
from (irb):3
from :0
irb(main):004:0> VERSION
=> “1.8.7”
On 22.10.2010 22:09, Ed Howland wrote:
I searched in vain for the answer, but why doesn’t yield work inside
Ruby 192 blocks. The syntax allows you to pass the blocks as a&blk
param, but you have to call the block with blk.call. If you try to use
yield, you get a LocalJumpError:
This isn’t something new in 1.9.2. There is no version of Ruby that I
am aware of that would allow this.
ruby-1.9.2-p0> meth(1) {|x,&blk| puts "in blok " + x.to_s; blk.call 2}
in blok 1
in meth 2
There are also other useful usecases for this, namely defining methods
with a block dynamically
in some class
define_method :foo do |x,y,&b|
puts “before”
yield # or b.call
puts “after”
end
Kind regards
robert
On Fri, Oct 22, 2010 at 3:09 PM, Ed Howland [email protected]
wrote:
Hi,
I searched in vain for the answer, but why doesn’t yield work inside
Ruby 192 blocks. The syntax allows you to pass the blocks as a &blk
param, but you have to call the block with blk.call. If you try to use
yield, you get a LocalJumpError:
I always figured it was because it was enclosing its environment, and
having
yield in the block and the environment could bet ambiguous.
def sort_proxy(collection)
collection.sort! do |a,b|
yield a , b # yield in a block
end
end
ary = [4,2,9,3,1]
sort_proxy ary do |a,b|
a <=> b
end
ary # => [1, 2, 3, 4, 9]
Josh C. wrote in post #956495:
I always figured it was because it was enclosing its environment, and
having
yield in the block and the environment could bet ambiguous.
Yes, I believe that’s the case. Consider:
def foo # <- block passed implicitly
bar do |&baz|
yield 123 # <- invokes the outer block
end
end
I think of ‘yield’ like ‘return’. ‘yield’ invokes the block passed in to
the enclosing method, and ‘return’ returns from the enclosing method.