这可能很简单,但是我不明白为什么该语句不是有效的Ruby代码:
3.>5 || 3.>2
SyntaxError: unexpected tINTEGER, expecting end-of-input
为什么这个是:
3.>5 || 3.> #this seems nonsensical
=> false
为什么在我的书中,这本书似乎给出了误导性的答案
3.>5 || 3.>(2)
=> false
但是,这给出了正确的答案
3.>(5) || 3.>(2)
=> true
答案 0 :(得分:3)
Ruby对空间敏感,与本网站中使用的语法突出显示工具不同,Ruby在解析运算符时采用了“最大munch”。
post_data = json.loads(request.body)
与3.<
不同,因为3. <
解析为“将<消息发送到整数3。”
添加一个空格。更好的是,仅出于这个原因,永远不要留下悬挂点,并输入代码.<
。
接下来,由于Ruby神奇的消失括号,3.0 < 1
解析为3.>5 || 3.>(2)
。遵循您的样式指南,并在几乎所有二进制运算符周围添加空格。少数不应该使用的惯用法是3.>(5 || 3.>(2))
,.
,.&
,..
等...
答案 1 :(得分:2)
这里的困惑是由于使用.
来使Ruby将比较分析作为方法调用,而不是更普通的二进制运算符(例如3 > 2
)。在Ruby运算符中,诸如>
最终是handled as methods,但是解析器具有特殊情况,允许您使用更熟悉的语法。
如果您想象对整数有一个称为gt
的方法,然后用它而不是>
重写示例,那么可能会更清楚。
您的第一个示例3.>5 || 3.>2
将等效于:
3.gt 5 || 3.gt 2
Ruby尝试将其解析为
3.gt (5 || 3.gt) 2
最后的2
是Ruby抱怨的unexpected tINTEGER
。
第二个示例3.>5 || 3.>
将被解析为以下内容:
3.gt (5 || 3.gt)
这似乎是荒谬的,因为我们知道gt
实际上是二进制运算符>
,并且它应该有第二个运算符。由于Ruby将其解析为一种方法,因此无法知道应该有多少个参数。据解析器所知,gt
方法可能不会期望任何参数(我们可以修补猴子>
而不会期望参数)。由于表达式5 || 3.>
的求值短路到5
,因此3.>
部分从不执行,因此不会发生错误。
如果您编写相同的表达式但不使用.
,则Ruby解析器将知道这是一个二进制运算符,并且将期望第二个运算符:
eval '3>5 || 3 >'
SyntaxError: (eval):1: syntax error, unexpected end-of-input
3>5 || 3 >
^
最后一个示例3.>(5) || 3.>(2)
将解析为:
3.gt(5) || 3.gt(2)
由于括号中没有歧义,很明显2
是方法调用的参数,因此您可以得到正确的答案。