On Dec 17, 2:11 am, Chiyuan Z. [email protected] wrote:
bar { puts “foo” }
as &brk . I know one solution is
def bar
foo { yield }
end
but that create another block, not the original one.
The article you mention is not loading for me (nor is googles cached
version), so I’m not sure exactly what you mean. When you pass a block
as a parameter, it’s just an explicit reference to the implicit block,
not a new copy:
def bar(&blk_2)
puts blk_2.object_id
end
def foo(&blk_1)
puts blk_1.object_id
bar(&blk_1)
end
puts “implicit block”
foo { “baz” }
puts “explicit block”
prc = lambda { “baz” }
puts prc.object_id
foo(&prc)
=>
implicit block
-605770738
-605770738
explicit block
-605770758
-605770758
-605770758
Although it is slightly slower to grab a reference to the block, it’s
probably not anything you have to worry about. E.g., it’s only half as
slow over 100,000 calls for this benchmark:
require “benchmark”
def implicit_blk
yield “baz”
end
def explicit_blk(&blk)
blk.call(“baz”)
end
n = 100_000
Benchmark.bm(10) { | x |
x.report(“implicit”) { n.times { implicit_blk { | y | y } } }
x.report(“explicit”) { n.times { explicit_blk { | y | y } } }
}
=>
user system total real
implicit 0.370000 0.080000 0.450000 ( 0.478676)
explicit 1.200000 0.090000 1.290000 ( 1.324176)
…for me, that’s not anything to be concerned about.
Edit: Ah, the cached version of the article you mention just loaded.
Looks like the author got a larger variance in his benchmark. I just
ran the above benchmark again for 1,000,000 calls (like the article),
with these results:
user system total real
implicit 3.520000 0.640000 4.160000 ( 5.230353)
explicit 12.180000 0.850000 13.030000 ( 15.966038)
…so indeed, passing an explicit reference to the block seems to be
exponentially slower. However, still, 3 times slower over a million
calls still doesn’t bother me very much. YMMV.
Regards,
Jordan