在括号中包含参数时,Ruby Kernel.raise方法会引发错误

时间:2012-03-30 08:55:46

标签: ruby parentheses raise

我喜欢用括号括起来的方法参数,这是一些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

我可以没有它,我只是想知道为什么这会以错误结束。

2 个答案:

答案 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>