我喜欢用括号括起来的方法参数,这是一些Pascal的怀旧之情。清理代码时,如果我找不到没有它的方法参数,我会立即将它们包含起来。 今天它导致我的工作代码抛出错误,虽然根据文档我的语法看起来没问题。
Kernel.raise的文档具有以下格式:
(Object) raise(exception[, string [, array]])
这些都有效:
> raise TypeError
TypeError: TypeError
> raise (TypeError)
TypeError: TypeError
> raise "Error message"
RuntimeError: Error message
> raise ("Error message")
RuntimeError: Error message
但是下一个抛出语法错误的封闭版本:
> raise TypeError, "Error message"
TypeError: Error message
> raise (TypeError, "Error message")
SyntaxError: unexpected ')', expecting $end
我可以没有它,我只是想知道为什么这会以错误结束。
答案 0 :(得分:5)
你可能已经知道,在惯用的Ruby中,永远不会在方法的结尾和括号中的参数列表之间插入空格。 Some风格指南explicitly forbid it。
也有一个实用的理由。
1.9.2-p290 > def concat(a, b)
1.9.2-p290 > a + b
1.9.2-p290 > end
1.9.2-p290 > concat 'foo', 'bar'
=> "foobar"
1.9.2-p290 > concat('foo', 'bar')
=> "foobar"
1.9.2-p290 > concat ('foo', 'bar')
SyntaxError: (irb):27: syntax error, unexpected ',', expecting ')'
以这种方式调用任何方法都会遇到错误,而不仅仅是Kernel.raise
。
我不熟悉Ruby内部,但我想这样做的原因是,当一个空格位于参数列表之前时,Ruby期待“no-parens”风格。所以当然这很有效:
1.9.2-p290 :035 > concat ("bar"), ("foo")
=> "barfoo"
据推测,Ruby正在尝试在将结果传递给方法之前评估每个带括号的表达式的内容。我推测写raise (TypeError, "Error message")
是要求Ruby只评估TypeError, "Error message"
,这当然会失败。
答案 1 :(得分:3)
圆括号用于Ruby中的表达式分组和优先级覆盖。所以,当你说
时foo (bar, baz)
您正在使用单个参数发送消息:foo
,该参数是评估表达式bar, baz
的结果。并且bar, baz
不是有效的表达式,因此您获得了SyntaxError
。
foo (bar)
有效,因为bar
是一个有效的表达式。
foo (if bar then baz else quux end)
也可以。
如果您希望Ruby解释括号而不是表达式分组但是为了传递多个参数以及消息send,则左括号需要直接跟随消息选择器:
foo(bar, baz)
这与Kernel#raise
,BTW无关。您无法在Ruby中更改消息发送的语法(事实上,您无法在Ruby中更改任何语法),因此Kernel#raise
的任何内容对于其他所有方法都必须为真。 / p>