-
Proc.new vs lambda vs proc
Proc objects are blocks of code that have been bound to a set of local variables. Once bound, the code may be called in different contexts and still access those variables.
def gen_times(factor) return Proc.new { |n| n*factor } end times3 = gen_times(3) times5 = gen_times(5) times3.call(12) #=> 36 times5.call(5) #=> 25 times3.call(times5.call(4)) #=> 60So what is “lambda” business about then? lambda is a method in the Kernel module, which is mixed in to every object, and so available EVERYWHERE in your code. lambda returns a object of class Proc, but it checks it’s arguments when it is called, i.e. it must be called with precisely the amount of arguments the block expects or an ArgumentError is raised.
@proc = Proc.new { |a,b,c| puts [a,b,c].inspect } @lambda = lambda { |a,b,c| puts [a,b,c].inspect } @proc.call 1,2,3 # => [1,2,3] @lambda.call 1,2,3 # => [1,2,3] # Proc is chilled out. Proc just ignores any more arguments than it is expecting @proc.call 1,2,3,4,5,6,7,8 # => [1,2,3] # Procs also pass in nil in lieu of missing arguments @proc.call 1,2 # => [1, 2, nil] # lambda is not so chill @lambda.call 1,2,3,4,5,6,7,8 # => ArgumentError: wrong number of arguments (8 for 3) @lambda.call 1,2 # => ArgumentError: wrong number of arguments (2 for 3)Ok, what about this proc fellow then? The answer to that question is “That depends. Which version of Ruby do you use?”
In Ruby 1.8.7 and earlier proc is synonymous with lambda. They do the same thing, i.e. return a proc object that checks its arguments when called. To me this represents the wrong behaviour.
Maybe it’s just me, but I would expect proc to be a shortcut of Proc.new instead of a synonym for lambda. Something like this:
module Kernel def proc(&block) Proc.new &block end endln Ruby 1.9 that is exactly what it is, a convenient syntax for Proc.new. It is because of this I advise you never use it in your code, as it behaves very differently between these versions and you’re just asking for trouble as 1.9 adoption increases.
Recapitulation:
- Proc.new - Instantiates Proc that is agnostic re arguments
- lambda - Instantiates Proc that checks arguments
- proc - Inconsistent behaviour between 1.8 and 1.9 therefore avoid.
S
Sun28Mar