分部操作员认为是正则表达式分隔符

时间:2014-03-06 14:48:56

标签: ruby

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表达式?

3 个答案:

答案 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文字。