What's the difference between these two block passing strate

A common complaint I hear about Ruby is (I think, I may quoting
incorrectly or the wrong thing) that “blocks aren’t first order object.”
I
won’t pretend to know what that means but, in context, it appears that
they
are complaining about how you can’t pass blocks around like variables.
In
particular, I recall someone having to deal with some kind of UI toolkit
that requied blocks but couldn’t pass the blocks up the call stack.
I was just fiddling around with Ruby and I think I have two ways to
do
this and I was wondering if there were any subtle differences between
them
or any gatchas that I might be missing.
Please take a look at them. Here’s the first:

def foo
yield
end

def bar(&lambda)
foo &lambda
end

bar { puts “Blocks!” }

...and here's the second:

def foo
yield
end

def bar
foo { yield }
end

bar { puts “Blocks!” }

...so, what do you guys think?  Are they equivalent?  Is there a

performance difference? Are they even doing what I think they’re doing?
Thank you…

…so, what do you guys think? Are they equivalent? Is there
a performance difference? Are they even doing what I think
they’re doing?

They are not equivalent. Version A has to convert a block into
a Proc, which slows it down. Version B uses two calls instead
of just one, which slows it down.

Which one wins? See below. The difference in speed is
significant.

gegroet,
Erik V. - http://www.erikveen.dds.nl/


$ cat test.rb
require “ev/ruby”

module A
def self.foo
yield
end

def self.bar(&lambda)
foo &lambda
end
end

module B
def self.foo
yield
end

def self.bar
foo { yield }
end
end

def test(mod)
bm mod do
100_000.times do
mod.bar { :OK }
end
end
end

10.times do
test(A)
test(B)
end

$ ruby test.rb
CPU ELAPSED COUNT CPU/COUNT LABEL
18.926000 18.995000 10 1.892600 A
2.264000 2.265000 10 0.226400 B

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs