Why are parenthesis sometimes required in Ruby?

后端 未结 2 1011
庸人自扰
庸人自扰 2021-01-21 04:29

I recently ran into an oddity while looking at some Ruby code from the Rails docs.

Ruby lets you pass arguments like these examples:

redirect_to post_url         


        
相关标签:
2条回答
  • 2021-01-21 04:35

    Because { ... } has two meanings: hash literal and block.

    Consider this:

    %w(foo bar baz).select { |x| x[0] == "b" }
    # => ["bar", "baz"]
    

    Here, { ... } is a block.

    Now imagine that you are calling a method on the current object, so the explicit receiver is not needed:

    select { |x| x[0]] == "b" }
    

    Now imagine that you don't care about the parameter:

    select { true }
    

    Here, { true } is still a block, not a hash. And so it is in your function call:

    redirect_to { action: 'atom' }
    

    is (mostly) equivalent to

    redirect_to do
      action: 'atom'
    end
    

    and it is nonsense. However,

    redirect_to({ action: atom' })
    

    has an argument list, consisting of a hash.

    0 讨论(0)
  • 2021-01-21 04:48

    Curly braces serve double-duty in Ruby. They can delimit a hash, but they can also delimit a block. In this case, I believe your second example is getting parsed as:

    redirect_to do
      action: 'atom' 
    end, alert: "Something serious happened"
    

    Therefore your action: 'atom', which is not valid as an independent expression, gets parsed as such.

    The parentheses serve to disambiguate the {...} as a hash.

    0 讨论(0)
提交回复
热议问题