一元运算符的行为
在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]]]]]