Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing block into a method - Ruby [duplicate]

Tags:

ruby

block

I have a little question on passing block.

def a_method(a, b)
  a + yield(a, b)
end

This works fine.

k = a_method(1, 2) do |x, y| 
  (x + y) * 3 
end
puts k

But this won't work.

puts a_method(1, 2) do |x, y| 
  (x + y) * 3 
end
# LocalJumpError: no block given (yield)

Can anyone kindly explain this to me?

Thanks. Example taken from Metaprogramming Ruby by Paolo Perrotta. Great book.

like image 367
revolver Avatar asked Jun 08 '26 08:06

revolver


1 Answers

The difference between do .. end and curly braces is that the curly braces bind to the rightmost expression, while do .. end bind to the leftmost one. Observe the following examples:

def first(x=nil)
  puts "  first(#{x.inspect}): #{block_given? ? "GOT BLOCK" : "no block"}"
  "f"
end

def second(x=nil)
  puts "    second(#{x.inspect}): #{block_given? ? "GOT BLOCK" : "no block"}"
  "s"
end

first second do |x| :ok end #   second(nil): no block
                            # first("s"): GOT BLOCK

first second {|x| :ok }     #   second(nil): GOT BLOCK
                            # first("s"): no block

In the first case, the block made with do..end will be bound to the first function (leftmost). In the second case the block made with curly brackets will be bound to the second function (rightmost).

Usually it's good idea to use parentheses if you have two functions and a block - just for readability and to avoid mistakes.

It's very easy to accidentally pass a block to puts method, just as in your question.

like image 134
Arsen7 Avatar answered Jun 10 '26 02:06

Arsen7



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!