tags:

views:

50

answers:

2
s = Proc.new {|x|x*2}
puts "proc:" + (s.call(5)).to_s

def foo(&a)
    a.call(5)
end
foo{|x| puts "foo:" + (x*3).to_s}

Running this program produces the output:

proc:10
foo:15

How does the value 3 from the foo block get passed to the proc? I expected this output:

proc:10
foo:10

The proc is always called with the value 5 as the argument because foo is defined as:

    a.call(5)

Why is foo 15 in the output?

+4  A: 

Because the block outputs x*3 (as opposed to s which returns x*2) and 5*3 is 15.

sepp2k
When I call foo, what happens to a.call(5)? It's ignored? I thought it would be called and the output would be 10.
uzo
@uzo: `a` is the block `{|x| puts "foo:" + (x*3).to_s}`. This block multiplies the argument times 3. So when you call it with the argument 5, you get 5*3, which is 15.
Chuck
Of course it's not ignored. a is called with the argument 5. a then outputs 5*3, which is 15.
sepp2k
@Chuck: a is block! Thanks. I mistakenly thought a.call(5) would invoke the Proc I had defined at the beginning, passing the foo block as an argument. Now that I think about it that doesn't make a whole lot of sense.
uzo
+3  A: 

The value 3 does not get passed to the proc because you're not passing s to foo. You probably meant to write

foo {|x| puts "foo: #{s.call(x)}"}

or

puts "foo: #{foo(&s)}"

Additionally, these are equivalent:

def foo_1(x, &a)
  puts a.call(x)
end
def foo_2(x)
  puts yield(x)
end

foo_1(5, &s) #=> 10
foo_2(5, &s) #=> 10
glenn jackman