4

I've been playing with the Codecademy Ruby course and there's an exercise on lambdas and Procs. I do understand the difference, but I don't quite see why the first code listing here works, while the second does not.

Why does this work:

def batman_ironman_proc
  p = Proc.new { return "Batman will win!" }
  p.call
  "Iron Man will win!"
end

puts batman_ironman_proc  # prints "Batman will win!"

But not this:

def batman_ironman_proc(p)
  p.call
  "Iron Man will win!"
end

p = Proc.new { return "Batman will win!" }
puts batman_ironman_proc(p)  # unexpected return
ybakos
  • 8,152
  • 7
  • 46
  • 74
  • Have a look at http://stackoverflow.com/questions/1435743/why-does-explicit-return-make-a-difference-in-a-proc – eugen Feb 08 '13 at 14:49

1 Answers1

3

It's because of how proc behaves with control flow keywords: return, raise, break, redo, retry and etc.

These keywords will jump from the scope where the proc is defined, otherwise the lambda has its own scope so those keywords will jump from lambda's scope.

In your second example the proc is defined in the scope of main. And as tadman commented below, you can't return from main, only exit available.

Your code will work if you switch from proc to lambda.

megas
  • 21,401
  • 12
  • 79
  • 130
  • You can't `return` from main. You can only `exit`. – tadman Feb 08 '13 at 15:31
  • I found another explanation from the Oreilly Ruby book: "the `return` statement returns from the lexically enclosing method, even when the statement is contained within a block. [...] A proc is like a block, so if you call a proc that executes a return statement, it attempts to return from the method that encloses the block that was converted to the proc. – ybakos Feb 08 '13 at 23:20