Ruby(ruby 2.0.0p195(2013-05-14)[x64-mingw32])正在解析序列“ident-space-slash-number”作为开始常规epxression的事情:
irb(main):030:0> x = 10
=> 10
irb(main):031:0> x /2
irb(main):032:0/ /
SyntaxError: (irb):32: unterminated regexp meets end of file
(第32行就是让irb完成解析。在第31行的末尾,第一个/
已被视为正则表达式分隔符。)
使用不同的间距或不同的运算符,它可以按预期工作:
irb(main):033:0> x / 2
=> 5
irb(main):034:0> x/ 2
=> 5
irb(main):035:0> x/2
=> 5
irb(main):036:0> x *2
=> 20
这是一个错误吗?基于什么假设解析器在这种情况下会看到一个reqular表达式?
答案 0 :(得分:4)
首先,运行irb
并启用警告,以便更好地了解正在发生的事情(省略不相关的警告):
$ irb -w
irb:001> x = 0
=> 0
irb:002> x /2
irb:003/ /
(irb):2: warning: `/' after local variable or literal is interpreted as binary operator
(irb):2: warning: even though it seems like regexp literal
SyntaxError: (irb):3: unterminated regexp meets end of file
在第2行,Ruby lexer检测到x
是一个局部变量,因此它假设以下/
是二进制运算符而不是正则表达式的开头。在第3行引发错误,因为/
本身是一个不完整的正则表达式。
这是因为IRB使用lexer来确定您输入的表达式是否完整,因此可以发送给Ruby执行,或者如果您需要提供更多输入来完成表达式。 IRB的词法分析器无法检测x
是什么,因此它假定它是一种方法并尝试将该行的其余部分(/2
)解释为x
的参数,因为它是一个未终止的正则表达式IRB要求您在第3行完成它,因此IRB发送给Ruby解析器的代码无效,如上所述。
为了进行比较,请考虑当x
实际上是一种方法时会发生什么:
$ irb -w
irb:001> def x; end
=> :x
irb:002> x /2
irb:003/ /
(irb):2: warning: ambiguous first argument; put parentheses or even spaces
ArgumentError: wrong number of arguments (1 for 0)
from (irb):1:in `x'
from (irb):2
在这种情况下,Ruby和IRB都同意表达式必须被解析的方式,并且您遇到错误,因为您试图将参数(即/2\n/
)传递给x
方法没有预料到。
要点:这是一个bug还是没有?也许这是一个错误,或者只是妥协,以保持IRB的词法分析器简单,我无法分辨。
答案 1 :(得分:0)
正如你所定义的x = 10
。 Ruby解析器确定x
是局部变量。但是现在当你写x /2
时,Ruby希望,还有一个名为x
的方法,x /2
被视为x(/2)
。但是/2
在语法上是不正确的,所以Ruby似乎要给方法x
一个regexp对象。但是在写/
的最后一行中,Ruby解析器仍然存在同样的困惑。因此它抱怨,你的正则表达式文字是未终止的。
答案 2 :(得分:0)
这部分是为了赞美Arup的回答
查看Regexp class文档。开头的段落说:
...使用/.../和%r {...}文字以及Regexp :: new构造函数创建正则表达式...
正如Arup所说,ruby解析器将行的/2
部分解释为Regexp文字创建的开始,与"2
被解释为的方式非常相似开始创建一个String文字。