Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does explicit return make a difference in a Proc?

def foo   f = Proc.new { return "return from foo from inside proc" }   f.call # control leaves foo here   return "return from foo"  end  def bar   b = Proc.new { "return from bar from inside proc" }   b.call # control leaves bar here   return "return from bar"  end  puts foo # prints "return from foo from inside proc"  puts bar # prints "return from bar"  

I thought the return keyword was optional in Ruby and that you are always returning whether you request it or not. Given that, I find it surprising that foo and bar have different output determined by the fact that foo contains an explicit return in Proc f.

Does anyone know why this is the case?

like image 986
uzo Avatar asked Sep 16 '09 22:09

uzo


People also ask

What is the main difference between procs and lambdas?

There are only two main differences. First, a lambda checks the number of arguments passed to it, while a proc does not. This means that a lambda will throw an error if you pass it the wrong number of arguments, whereas a proc will ignore unexpected arguments and assign nil to any that are missing.

What is the difference between a lambda a block and a proc?

When using parameters prefixed with ampersands, passing a block to a method results in a proc in the method's context. Procs behave like blocks, but they can be stored in a variable. Lambdas are procs that behave like methods, meaning they enforce arity and return as methods instead of in their parent scope.

What is the difference between PROC and block?

Procs are objects, blocks are notA proc (notice the lowercase p) is an instance of the Proc class. This lets us call methods on it and assign it to variables. Procs can also return themselves. In contrast, a block is just part of the syntax of a method call.

What are Ruby procs?

A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another Proc, and can be called. Proc is an essential concept in Ruby and a core of its functional programming features.


1 Answers

Ruby has three constructs:

  1. A block is not an object and is created by { ... } or do ... end.
  2. A proc is a Proc object created by Proc.new or proc.
  3. A lambda is a Proc created by lambda (or proc in Ruby 1.8).

Ruby has three keywords that return from something:

  1. return terminates the method or lambda it is in.
  2. next terminates the block, proc, or lambda it is in.
  3. break terminates the method that yielded to the block or invoked the proc or lambda it is in.

In lambdas, return behaves like next, for whatever reason. next and break are named the way they are because they are most commonly used with methods like each, where terminating the block will cause the iteration to resume with the next element of the collection, and terminating each will cause you to break out of the loop.


If you use return inside the definition of foo, you will return from foo, even if it is inside a block or a proc. To return from a block, you can use the next keyword instead.
def foo   f = Proc.new { next "return from foo from inside proc" }   f.call # control leaves foo here   return "return from foo"  end puts foo # prints "return from foo" 
like image 98
sepp2k Avatar answered Sep 21 '22 13:09

sepp2k