From: Joel VanderWerf Date: 2004-06-02T08:01:00+09:00 Subject: Re: Blocks and Closures Gavin Sinclair wrote: > On Wednesday, June 2, 2004, 6:38:19 AM, Joel wrote: > > >>You're right, there's no reason to use the &bl notation. You can use the >>Kernel#block_given? method: > > > > Just a note for the OP. The following example shows the advantage of > the &block notation in certain circumstances. > > def bar > return 5 + yield > end > > def foo(&block) > bar(block) > end > > 'foo' is now a proxy for 'bar'. Slight nit: 'bar(block)' should be 'bar(&block)', if you want to propagate the block. Actually, though, there is a more efficient way to propagate a block: def bar return 5 + yield end def foo bar {yield} end p foo {3} # ==> 8 I guess it's more efficient because no Proc object is created. This technique doesn't work if you need to store the block somewhere for later access. Then you really do need to use & or Proc.new. Here's some benchmarking (ruby-1.9.0): require 'benchmark' def outer11(&bl) inner1(&bl) end def outer12(&bl) inner2(&bl) end def outer21 inner1 {yield} end def outer22 inner2 {yield} end def inner1(&bl) bl.call end def inner2 yield end n = 100000 Benchmark.bmbm(10) do |rpt| rpt.report("outer11") do n.times {outer11{}} end rpt.report("outer12") do n.times {outer12{}} end rpt.report("outer21") do n.times {outer21{}} end rpt.report("outer22") do n.times {outer22{}} end end __END__ Output: Rehearsal --------------------------------------------- outer11 1.850000 0.010000 1.860000 ( 1.856130) outer12 1.600000 0.000000 1.600000 ( 1.600134) outer21 2.210000 0.000000 2.210000 ( 2.214836) outer22 0.520000 0.000000 0.520000 ( 0.526088) ------------------------------------ total: 6.190000sec user system total real outer11 1.870000 0.000000 1.870000 ( 1.871797) outer12 1.620000 0.000000 1.620000 ( 1.623072) outer21 2.230000 0.000000 2.230000 ( 2.236854) outer22 0.500000 0.000000 0.500000 ( 0.501914)