Ruby blocks, procs and lambdas
Last update
2018-03-08
2018-03-08
« — »
Proc and lambda
Both types are anonymous functions and a lambda
is just a special instance of Proc
, their differences are:
- Lambdas are defined with
->() {}
orlambda() {}
and procs withProc.new {}
orproc{}
- Procs return from the current method (as they become part of the caller method), while lambdas return from the lambda itself (like calling a different method).
- Procs do not care about the correct number of arguments, while lambdas will raise an exception.
1 2 3 4 5 6 7 8 | l = -> { puts 'this is a lambda' } l.class # Proc l.lambda? # true l.call # "this is a lambda" l = ->(n) { n * 2 } # lambda with arguments l.call 3 # 6 l.call 3, 4 # ArgumentError: wrong number of arguments |
Pay attention at the different return behaviour:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | l = -> { return 1 } p = Proc.new { return 1} puts l.call # 1 puts p.call # we cannot call return from the top-level context: # LocalJumpError: unexpected return def foo p = proc{ return 1} puts 'before' puts p.call # we can call return from a non top-level context puts 'after' end foo # before # 1 |
block
A block
is an instance of Proc passed as a parameter to a method.
1 2 3 4 5 6 7 8 9 10 11 | def implicit_block yield 1, 2, 3 if block_given? # execute block if passed end def explicit_block(&block) block.call 1, 2, 3 if block_given? # execute block if passed implicit_block &block # you can pass the block to another method end implicit_block{|p1, p2, p3| puts p1+p2+p3 } # prints 6 explicit_block{|p1, p2, p3| puts p1+p2+p3 } # prints 6 two times |
Source: blackbytes, sitepoint closures