0

Apologies for not knowing how to state this question better.

I was noticing how the block syntax of {} binds to the object immediately to the left, and then noticed the do/end binds to the object that starts the line. In the process, I noticed this:

def a(*)
  puts "a: #{block_given?}"
end

def b 
  puts "b: #{block_given?}" 
end

a b {}
#=> b: true
#=> a: false
a b do end  
#=> b: false
#=> a: true

The confusing thing is I don't need the (*) operator (or any parameter there) on method 'b' and both the method call lines result in the same error.

I'm just not sure what's going on that if I don't have a (*) parameter in method 'a' then it says "Wrong number of arguments 1 for 0", but what was the argument that I passed? And why was it only given to 'a'?

Wayne Conrad
  • 103,207
  • 26
  • 155
  • 191
Tony DiNitto
  • 1,244
  • 1
  • 16
  • 28

1 Answers1

2
a b {}       # a(b{})
a b do end   # (a(b)) do end

a(b do end)  # behaves like a b {}  

The parser binds { tightly to the token that precedes it. If you omit the parentheses around method arguments, a curly braces block will be associated with the last argument - probably unwanted.

steenslag
  • 79,051
  • 16
  • 138
  • 171