Why do parentheses affect hashes?

hash, ruby, syntax

Solution

When calling a method, the opening curly bracket directly after the method name is interpreted as the start of a block. This has precedence over the interpretation as a hash. One way to circumvent the issue is to use parenthesis to enforce the interpretation as a method argument. As an example, please note the difference in meaning of these two method calls:

# interpreted as a block
[:a, :b, :c].each { |x| puts x }

# interpreted as a hash
{:a => :b}.merge({:c => :d}) 

Another way is to just get rid of the curly brackets as you can always skip the brackets on the last argument of a method. Ruby is "clever" enough to interpret everything which looks like an association list at the end of an argument list as a single hash. Please have a look at this example:

def foo(a, b)
  puts a.inspect
  puts b.inspect
end

foo "hello", :this => "is", :a => "hash"
# prints this:
# "hello"
# {:this=>"is", :a=>"hash"}

Problem

When I used `respond_with` and passed a literal hash, it gave me the error: ``` syntax error, unexpected tASSOC, expecting '}' `respond_with {:status => "Not found"}` ``` However, when I enclosed the literal hash in parentheses like so: ``` respond_with({:status => "Not found"}) ``` the function runs without a hitch. Why do the parentheses make a difference? Isn't a hash an enclosed call?

Original source