Method Definitions: &block vs. yield()


#1

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


#2

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 G. II


#3

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.


#4

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


#5

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


#6

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

#7

On 2/7/06, Robert K. removed_email_address@domain.invalid 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 F.


#8

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 W.