Hi --
def f(&b)
...
b.call
...
end
def g
...
yield b
...
end
As far I understood the documentation for call and yield, both are
equivalent:
f { ... }
g { ... }
Is there a principal reason when to prefer call over yield (or vice
versa), or are these only syntactic variations of the same feature?
I think you mean just yield (not yield b).
yield is a lot faster:
david-a-blacks-computer:~/hacking dblack$ ruby yi.rb
require 'benchmark'
include Benchmark
def x(&b)
b.call
end
def y
yield
end
n = 1000000
bmbm do |b|
b.report("b") { n.times { x {} } }
b.report("y") { n.times { y {} } }
end
Rehearsal -------------------------------------
b 3.760000 0.010000 3.770000 ( 3.770292)
y 0.590000 0.000000 0.590000 ( 0.595891)
---------------------------- total: 4.360000sec
user system total real
b 3.780000 0.000000 3.780000 ( 3.784505)
y 0.610000 0.000000 0.610000 ( 0.609034)
So I'd only use the &b/call version if you really need the thing as an
object. I also consider yield more idiomatic, or something... since
the whole anatomy of the method call is designed to provide the extra
component (the code block). When you capture the block as a proc,
you're capturing a syntactic construct as an object -- sort of like:
def x %arg_list # imaginary example
where arg_list was an ArgumentList object. That's logically secondary
to the presence of the argument list in the first place, and similarly
the block exists prior to, and independently of, the fact that the
language lets you capture it in a variable.
David
--
* Books:
RAILS ROUTING (new!
http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (
http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (
http://www.rubypal.com)