Search code examples
rubybindingblocksplat

In Ruby: I'm giving a method an argument somehow when calling it, but don't know where. I think it has something to do with block bindings?


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'?


Solution

  • 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.