Why does `puts(nil or 4)` fail in Ruby?

前端 未结 3 1934
猫巷女王i
猫巷女王i 2021-01-03 22:41

When I do:

puts(nil or 4)

Ruby complains:

SyntaxError: syntax error, unexpected ke         


        
3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-03 23:10

    @Sergio Tulentsev (and @sawa) gave a good answer, but I want to rephrase it so I can understand it quickly in the future:

    Ruby lets us drop parenthesis in function calls. That is, instead of:

    func1(ARG, ARG, ARG) or func2(ARG, ARG, ARG)
    

    We can do:

    func1 ARG, ARG, ARG or func2 ARG, ARG, ARG
    

    However, in order to make this last line behave like the first one, "or" can't be an operator used in the top-level of an ARG (otherwise that last line will be interpreted as func1(ARG, ARG, ARG or func2 ARG, ARG, ARG)). Indeed, when we look in the BNF we see that ARG doesn't directly mention "or"/"and" (which means it's illegal there).

    But ARG still makes it possible to use "or": by wrapping the expression in parentheses. In the BNF we see this as the PRIMARY alternative that ARG can branch to (as PRIMARY, in its turn, branches to '(' COMPSTMT ')').

    Now, as to why func (1 or 2) and func((1 or 2)) work whereas func(1 or 2) doesn't:

    • func(1 or 2) is what the BNF calls FUNCTION, which expands to OPERATION ['(' [CALL_ARGS] ')'], which means the ARG is "1 or 2", but, as we've seen, ARG can't contain "or", so it's invalid.

    • func((1 or 2)) is, again, OPERATION ['(' [CALL_ARGS] ')'], but here the the ARG is "(1 or 2)", which is a valid ARG (see PRIMARY mentioned above).

    • func (1 or 2) is what the BNF calls COMMAND, which expands to OPERATION CALL_ARGS, which means the ARG is "(1 or 2)", which is a valid ARG (see PRIMARY mentioned above).

提交回复
热议问题