0

我试图让一个类的实例MyClass评估为一个虚假的值。所以我试图覆盖我能想到的所有方法来MyClass充当nil. 我有:

a = MyClass.new
a.nil? #=> true
a.class #=> NilClass
a == nil #=> true
a.eql? nil #=> true
a.equal? nil #=> true
a.instance_of? NilClass #=> true
a.kind_of? NilClass #=> true
a.is_a? NilClass #=> true

我什至得到了

nil == a #=> true
nil.eql? a  #=> true
nil.equal? a #=> true

最后我尝试了

a.__id__ #=> 4
nil.__id__ #=> 4
a.object_id #=> 4
nil.object_id #=> 4

但是,a将始终评估为true. 所以我想知道 Ruby 如何检查aisnilfalse. 我想这是开发人员无法访问的东西。

这不是要解决实际问题,我只是想知道它是否确实不能完成。我知道这会打破 Ruby 的“everything-ist-true-except-false-and-nil”-idiom,而且它很可能是一个纯粹的邪恶黑客。

4

2 回答 2

1

Ruby 检查表达式的实际值。

class Foo; end

f = Foo.new
f # => #<Foo:0x007ff3da88b348>

if f
  puts 'yay'
else
  puts 'nay'
end

无论您尝试在Foo类上重新定义什么方法,它f仍然是一个实例,Foo并且该检查将打印“yay”。你在这里无能为力。

于 2013-02-22T17:04:54.743 回答
1

只有两个对象评估为假。Ruby 只是检查对象是否是这两者之一。时期。

请注意,OO 的基础之一是模拟:一个对象可以模拟另一个对象。这不是真的:不可能模拟nilor false。这是 Ruby 违反 OO 的恼人案例之一,与Object#equal?.

于 2013-02-22T17:05:18.427 回答