在+
类的Ruby中重新定义一元Fixnum
运算符时,会产生一些奇怪的结果。不完全确定事情发生的原因(特别是行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
答案 0 :(得分:5)
我怀疑你看到解析器行为在解释数字文字方面的副作用。
如果我们创建自己的类:
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会看到非文字表达式并最终调用一元方法。同样,当您将一元运算符加倍时。
答案 1 :(得分:2)
这个答案为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]]]]]