Forum: Ruby Passing a block to a block

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-11-04 14:42
I notice that if you pass a block to a block, you can't use 'yield' to
yield to that block:

$ cat yield_in_block.rb
foo = lambda { |e| puts e }
blk = lambda { |e| yield e }
blk.call(123, &foo)

$ ruby yield_in_block.rb
yield_in_block.rb:2: no block given (LocalJumpError)
        from yield_in_block.rb:3
$ ruby19 yield_in_block.rb
yield_in_block.rb:2:in `block in <main>': no block given (yield)
(LocalJumpError)
        from yield_in_block.rb:3:in `call'
        from yield_in_block.rb:3:in `<main>'

What's the reason for this? Does 'yield' only invoke the top-level block
passed into a method?

ruby1.9 is happy but only if I explicitly reference the block to yield.

foo = lambda { |e| puts e }
blk = lambda { |e,&y| y[e] }
blk.call(123, &foo)

Thanks,

Brian.
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2008-11-04 20:20
(Received via mailing list)
Brian Candler wrote:
> I notice that if you pass a block to a block, you can't use 'yield' to
> yield to that block:
>
> $ cat yield_in_block.rb
> foo = lambda { |e| puts e }
> blk = lambda { |e| yield e }
> blk.call(123, &foo)
>

blk is not a block.  It is a Proc object or closure.
(Note that it isn't a Lambda object.  Lambda is
for Lisp weenies.)

> passed into a method?
>
> ruby1.9 is happy but only if I explicitly reference the block to yield.
>
> foo = lambda { |e| puts e }
> blk = lambda { |e,&y| y[e] }
> blk.call(123, &foo)

foo = proc{|x| puts x }
    ==>#<Proc:0x02b2ae60@(irb):1>
bar = proc{|x,prc| prc[x] }
    ==>#<Proc:0x02b24ac4@(irb):2>
bar[ 88, foo ]
88
    ==>nil
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-11-04 21:09
William James wrote:
> foo = proc{|x| puts x }
>     ==>#<Proc:0x02b2ae60@(irb):1>
> bar = proc{|x,prc| prc[x] }
>     ==>#<Proc:0x02b24ac4@(irb):2>
> bar[ 88, foo ]

Indeed, there's no problem when you pass them around and invoke them
explicitly.

My question (and I apologise if I didn't word it clearly) was regarding
the 'yield' keyword, to make a callback to a hidden proc which is not
one of the explicit arguments. e.g.

  def foo(*a,&b)
    yield 123      # similar to b.call(123)
  end

  pr = Proc.new { |x| puts x }
  foo(&pr)

This works fine as shown when passing to a method, but not when passing
to another Proc.
This topic is locked and can not be replied to.