Ruby Kernel.raise method throws error when enclosing parameters in parenthesis

回眸只為那壹抹淺笑 提交于 2019-12-02 06:44:21

You probably already know that in idiomatic Ruby one would never insert a space between the end of a method and an argument list in parenthesis. Some style guides explicitly forbid it.

There's a pragmatic reason too.

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 ')'

You'll encounter errors calling any method this way, not just Kernel.raise.

I'm not familiar with Ruby internals, but I would imagine the reason for this is that when a space precedes the argument list, Ruby is expecting the "no-parens" style. So of course this works:

1.9.2-p290 :035 > concat ("bar"), ("foo")
 => "barfoo"

Presumably Ruby is trying to evaluate the contents of each parenthesized expression before passing the result to the method. I'd speculate that writing raise (TypeError, "Error message") is asking Ruby to evaluate just TypeError, "Error message", which of course fails.

Parentheses are used for expression grouping and precedence override in Ruby. So, when you say

foo (bar, baz)

You are sending the message :foo with a single argument which is the result of evaluating the expression bar, baz. And bar, baz is not a valid expression, therefore you get a SyntaxError.

foo (bar)

works, because bar is a valid expression.

foo (if bar then baz else quux end)

would work, too.

If you want Ruby to interpret parentheses not for expression grouping but for passing multiple arguments along with a message send, the opening parenthesis needs to directly follow the message selector:

foo(bar, baz)

This has nothing to do with Kernel#raise, BTW. You cannot change the syntax for message sends in Ruby (in fact, you cannot change any syntax in Ruby), therefore whatever is true for Kernel#raise must also be true for every other method.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!