提问人:Dani 提问时间:1/25/2019 最后编辑:sawaDani 更新时间:1/25/2019 访问量:95
将对象与自身与 #include 进行比较时未使用自定义 == 运算符?
Custom == operator not used when comparing an object with itself with #include?
问:
的文档指定使用运算符检查包含。在使用自定义定义将对象与自身进行比较的情况下,我正在检查这一点:Array#include?
==
==
class Foo
def ==(other)
false
end
end
f = Foo.new
f == f # => false
在这种情况下,文档的描述并非如此,并且优先使用另一种机制:
[f].include?(f) # => true
这个机制是什么,它在哪里定义?
答:
0赞
Chien Nguyen
1/25/2019
#1
我刚刚检查了源代码: https://apidock.com/ruby/Array/include%3F
我相信 ruby 为此函数使用了默认运算符 () 而不是对象运算符。rb_equal
评论
5赞
Aleksei Matiushkin
1/25/2019
恰恰相反。 比较指针返回和 (调用 ),出于性能原因从不调用。rb_equal_opt(e, item)
true
rb_equal
#==
2赞
sawa
1/25/2019
拜托,Ruby 1.9.3 已经死了。至少检查一下 OP 引用的 Ruby 2.2.2,或者最新的 Ruby 2.6.0,这是可取的。
5赞
VP.
1/25/2019
#2
阅读源代码
VALUE
rb_ary_includes(VALUE ary, VALUE item)
{
long i;
VALUE e;
for (i=0; i<RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
switch (rb_equal_opt(e, item)) {
case Qundef:
if (rb_equal(e, item)) return Qtrue;
break;
case Qtrue:
return Qtrue;
}
}
return Qfalse;
}
从 https://ruby-doc.org/core-2.2.0/Array.html#method-i-include-3F 你会看到 Ruby 没有使用你的对象运算符
编辑:正如aleksei-matiushkin(在评论中)所述,比较指针并返回truerb_equal_opt(e, item)
反转它,你可以用:
class Foo
def ==(other)
puts "yay"
true
end
end
> f = Foo.new
=> #<Foo:0x0000000001048610>
> [f].include?(f)
=> true
> [f].include?(f.dup)
yay
=> true
评论
4赞
Aleksei Matiushkin
1/25/2019
它没有使用运算符,只是因为它实际上是同一个对象,并且指针的比较会立即返回。如果不是这种情况,将致电.最后一个子句是返回的内容。#==
true
rb_equal
#==
case Qtrue: return Qtrue;
true
0赞
Dani
1/25/2019
谢谢,现在有意义了!对我来说,缺少的部分是理解比较指针。浏览 Ruby 的源代码时,我仍然找不到这个文档,它是否在某个地方记录?rb_equal_opt
0赞
VP.
1/25/2019
@Dani你可以在这里找到它 github.com/ruby/ruby/blob/......
1赞
VP.
1/25/2019
@Dani,在这里读得很好 pawelniewiadomski.com/2017/03/21/......
1赞
Dani
1/25/2019
@VP 是的,我自己找到了定义,这是我缺少的文档:)看看这段代码,我并不清楚这实际上是指针比较。
评论
Array
==
include?