一元运算符的行为

Fixnum类中重新定义Ruby中的一元+运算符时有一些奇怪的结果。 不完全确定事情发生的原因(特别是第009行)。

 irb:003> class Fixnum irb:004> def +@ #define unary + irb:005> 15 irb:006> end irb:007> end => nil irb:008> 2 => 2 irb:009> +2 => 2 irb:010> +(2) => 15 irb:011> ++2 => 15 

我怀疑你看到解析器行为在解释数字文字方面的副作用。

如果我们创建自己的类:

 class C def +@ 11 end end 

然后看一些事情:

 > c = C.new > +c => 11 > ++c => 11 

这正是我们期望发生的事情。 如果我们使用你的Fixnum一元+覆盖和一个Fixnum变量:

 > n = 23 > +n => 15 > ++n => 15 

然后我们再次看到你所期待的。 在这两种情况下,我们都会看到在非文字上调用+@方法的结果。

但是,当我们与您的运营商一起考虑+6时:

 > +6 => 6 

不调用+@方法。 同样,如果我们覆盖-@

 class Fixnum def -@ 'pancakes' end end 

看看它做了什么:

 > -42 => 42 

那么这里发生了什么? 好吧,Ruby看到+6-42不是6.send(:+@)42.send(:-@)方法调用,而是作为正六和负四十二的单个文字。

如果你开始添加括号, +(6)-(42) ,那么Ruby会看到非文字表达式并最终调用一元方法。 同样当你将一元运算符加倍时。

这个答案为mu的答案增加了额外的细节。

刚刚了解了ruby的Ripper类,它清楚地显示了正在发生的事情:

 require 'ripper' p Ripper.sexp('2') # => [:program, [[:@int, "2", [1, 0]]]] p Ripper.sexp('+2') # => [:program, [[:@int, "+2", [1, 0]]]] p Ripper.sexp('+(2)') # => [:program, [[:unary, :+@, [:paren, [[:@int, "2", [1, 2]]]]]]] p Ripper.sexp('++2') # => [:program, [[:unary, :+@, [:@int, "+2", [1, 1]]]]]