Community Oriented
Gems
Web Based
Projects For Me
lambda, proc, and Proc.new
The difference between Ruby closure types, 15 Aug 2011
What is the difference between the many kinds of procs in Ruby? I realized while doing Ruby Kickstart that I didn't know. Did some research, and for each of these, there are two things to consider, how do they handle mismatched parameter arity, and how do they handle return statements.
lambda use this if you want it to behave like a method
Return statements return from the lambda.
def who_returns lambda { return "lambda" }.call return "method" end who_returns # => "method"
Like methods, you cannot mismatch parameter arity.
lambda { |one, two| }.call(1) # ~> wrong number of arguments (1 for 2) (ArgumentError)
proc avoid this since its behaviour differs across commonly used versions
In 1.8, it behaves like lambda and returns from the block. In 1.9, it behaves like Proc.new and returns from the environment.
def who_returns proc { return RUBY_VERSION + " proc" }.call return RUBY_VERSION + " method" end who_returns # => "1.8.7 method" # also for 1.8.6 who_returns # => "1.9.3 proc" # also for 1.9.1 and 1.9.2
In 1.8, it behaves like lambda and raises an error. In 1.9, it behaves like Proc.new and sets mismatched args to nil.
RUBY_VERSION # => "1.8.7" proc { |one, two| [one, two] }.call(1) # ~> wrong number of arguments (1 for 2) (ArgumentError) RUBY_VERSION # => "1.9.3" proc { |one, two| [one, two] }.call(1) # => [1, nil]
Proc.new use this if you want it to behave like a block
Return statements return from the environment.
def who_returns Proc.new { return "Proc.new" }.call return "method" end who_returns # => "Proc.new"
Like blocks, you can mismatch parameter arity.
Proc.new { |one, two| [one, two] }.call(1) # => [1, nil]
-> (stabby lambda) use it if you want method behaviour and you're in 1.9
The stabby lambda is just a 1.9 alternate syntax for lambda, so use it if you want method behaviour.
def who_returns -> { return "lambda" }.call return "method" end who_returns # => "method"
As a lambda, you can't mismatch arity.
->(one, two) { }.call(1) # ~> wrong number of arguments (1 for 2) (ArgumentError)