DEV Community


Discussion on: Understanding Ruby - Blocks, Procs, and Lambdas

3limin4t0r profile image
3limin4t0r • Edited

Another important difference between { } and do end is that { } has a higher precedence than do end. Like the documentation says:

do end has lower precedence than { } so:

method_1 method_2 {
  # ...

Sends the block to method_2 while:

method_1 method_2 do
  # ...

Sends the block to method_1.

The above is only relevant when omitting parentheses, but is still useful to know.

Jumping ahead to the Proc behavior with arguments, another thing that might be useful to know is that objects that have a #to_ary method (only arrays in core) will automatically be spread (splat) across the argument list if it is the sole argument to the proc. (Similar to what blocks do when an array is passed as the sole argument.)

pair = [3, 4]

proc_add = proc { |a, b| a + b }
proc_add.(pair) #=> 7 # auto spread/splat across proc arguments
proc_add.(*pair) #=> 7

lambda_add = ->(a, b) { a + b }
lambda_add.(pair) #=> ArgumentError (wrong number of arguments (given 1, expected 2))
lambda_add.(*pair) #=> 7

pair.then { |a, b| a + b } #=> 7 # auto spread/splat across block arguments
Enter fullscreen mode Exit fullscreen mode
baweaver profile image
Brandon Weaver Author

I seem to recall mentioning the first item somewhere, if not in this article. The second I always tend to forget, and there was one point that that behavior was broken for Lambdas and I had to use procs instead.