Forum: Ruby Method Definitions: &block vs. yield()

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.
90ebe8da17aabd36cc30d9f96a530e6f?d=identicon&s=25 James H. (Guest)
on 2006-02-06 23:39
(Received via mailing list)
Suppose I had two methods:

# First method
def my_first_method(b)
  yield b
end

# Second method
def my_second_method(&block)
  block.call
end

I know that the block in the 2nd example is converted to a Proc object,
but a Proc object (to my newb eyes) doesn't seem to hold any advantages
that might make me want to use the latter method.

I was wondering if there are specific advantages to using the &block
convention or yield()ing a block?  Is it merely a matter of preference
and or convention?

James
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-02-06 23:48
(Received via mailing list)
On Feb 6, 2006, at 4:38 PM, James H. wrote:

> I was wondering if there are specific advantages to using the &block
> convention or yield()ing a block?  Is it merely a matter of preference
> and or convention?

Well, once it's bundled up in an object you can tuck it away (assign
to a variable) and save it for a rainy day (execute it later).

James Edward Gray II
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-02-07 00:03
(Received via mailing list)
On Tue, 7 Feb 2006, James H. wrote:

> end
>
> I know that the block in the 2nd example is converted to a Proc object,
> but a Proc object (to my newb eyes) doesn't seem to hold any advantages
> that might make me want to use the latter method.
>
> I was wondering if there are specific advantages to using the &block
> convention or yield()ing a block?  Is it merely a matter of preference
> and or convention?
>
> James


     harp:~ > cat a.rb
     class C
       def foo(&b) bar &b end
       def bar() yield end
     end
     C::new.foo{ p 42 }


     harp:~ > ruby a.rb
     42


-a
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-02-07 00:03
(Received via mailing list)
James H. wrote:
> end
to be really comparable:

def my_second_method(b, &block)
   block.call(b)
end

> I know that the block in the 2nd example is converted to a Proc object,
> but a Proc object (to my newb eyes) doesn't seem to hold any advantages
> that might make me want to use the latter method.
>
> I was wondering if there are specific advantages to using the &block
> convention or yield()ing a block?  Is it merely a matter of preference
> and or convention?

Yield is lighter weight, since no Proc is created. Also, when a Proc is
created, it's binding is stored, and that binding includes any variables
in scope in the proc. As long as you hang on to that Proc, the values of
those variables cannot be GC-ed.

But with yield, you can only call the block from within the scope of the
method. If you need to store it away somewhere and call it after
returning, then you have to use a Proc.
B97225f66bb5caac601b12735d430a0d?d=identicon&s=25 Marcin MielżyÅ?ski (Guest)
on 2006-02-07 00:17
(Received via mailing list)
James H. wrote:

Generally yield is much faster than converting block to a Proc. But
there are situations when you have to explicitly pass the block and
convert it, these two are the most obvious that come to my mind:

saving a Proc object for delayed execution
implementing recursive iterators

lopex
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-02-07 10:00
(Received via mailing list)
Marcin MielżyÅ?ski wrote:
> James H. wrote:
>
> Generally yield is much faster than converting block to a Proc. But
> there are situations when you have to explicitly pass the block and
> convert it, these two are the most obvious that come to my mind:
>
> saving a Proc object for delayed execution
> implementing recursive iterators

More generally all situations where you do not want to invoke the block
from this method but pass it on to another.

Kind regards

    robert
Cff9eed5d8099e4c2d34eae663aae87e?d=identicon&s=25 Jacob Fugal (Guest)
on 2006-02-07 17:20
(Received via mailing list)
On 2/7/06, Robert Klemme <bob.news@gmx.net> wrote:
> More generally all situations where you do not want to invoke the block
> from this method but pass it on to another.

(or both)

Jacob Fugal
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2006-02-09 20:54
(Received via mailing list)
On Feb 6, 2006, at 6:03 PM, Joel VanderWerf wrote:
> But with yield, you can only call the block from within the scope
> of the method. If you need to store it away somewhere and call it
> after returning, then you have to use a Proc.

You can pass an implicit block to another method by wrapping it in
another block:

class Example

   def m1
      m2 { yield }
   end

   def m2
     yield
   end

end

e1 = Example.new

e1.m1 { p 42 }

There is no explicit reification of a block to a Proc object
in this example.  This technique can avoid the creation of
a Proc object in many common situations, but certainly not
in all cases.


Gary Wright
This topic is locked and can not be replied to.