Ruby的数组如何。|比较要素是否相等?

时间:2010-03-27 15:45:10

标签: ruby

以下是一些示例代码:

class Obj
  attr :c, true

  def == that
    p '=='
    that.c == self.c
  end
  def <=> that
    p '<=>'
    that.c <=> self.c
  end
  def equal? that
    p 'equal?'
    that.c.equal? self.c
  end
  def eql? that
    p 'eql?'
    that.c.eql? self.c
  end
end

a = Obj.new
b = Obj.new

a.c = 1
b.c = 1

p [a] | [b]

它打印2个对象,但它应该打印1个对象。没有调用任何比较方法。 Array怎么样。|比较平等?

3 个答案:

答案 0 :(得分:6)

Array#|是使用哈希实现的。因此,为了使您的类型能够很好地与它一起使用(以及使用哈希映射和哈希集),您必须实现eql?(您做过)和hash(您没有)。有意义地定义哈希的最直接的方法是返回c.hash

答案 1 :(得分:1)

Ruby的Array类是用C实现的,据我所知,在比较|中的对象时,使用自定义哈希表来检查是否相等。如果您想修改此行为,则必须编写自己的版本,使用您选择的相等检查。

要查看Ruby的Array#|click here的完整实现并搜索“rb_ary_or(VALUE ary1, VALUE ary2)

答案 2 :(得分:0)

Ruby正在调用哈希函数,并且它们返回不同的值,因为它们仍然只是返回默认的object_id。您将需要def hash并返回一些反映您对Obj重要性的想法。

>> class Obj2 < Obj
>>   def hash; t = super; p ['hash: ', t]; t; end
>> end
=> nil
>> x, y, x.c, y.c = Obj2.new, Obj2.new, 1, 1
=> [#<Obj2:0x100302568 @c=1>, #<Obj2:0x100302540 @c=1>, 1, 1]
>> p [x] | [y]
["hash: ", 2149061300]
["hash: ", 2149061280]
["hash: ", 2149061300]
["hash: ", 2149061280]
[#<Obj2:0x100302568 @c=1>, #<Obj2:0x100302540 @c=1>]