配列上の Ruby #union が非常に奇妙な反応をする
概要
私は Array#union または #| を使用するのが好きです。メソッドを使用して、重複が削除されたオブジェクトの配列を返します。 eql のカスタム実装がありますか?私のクラスで。 それを実行すると、本当に奇妙な動作が発生します。要素が 8 つまでの場合、結合は正常に機能しますが、要素がそれ以上になると重複は削除されません。それは実際には Ruby のバグなのでしょうか、それとも何か見落としているのでしょうか?
class A
attr_accessor :name
def initialize(name)
self.name = name
end
def eql?(other)
other.name.eql?(name)
end
end
as = names.map { |name| A.new(name) }
bs = names.map { |name| A.new(name) }
as | bs
=>
[#<A:0x00007fe503692388 @name="a">,
#<A:0x00007fe503692310 @name="b">,
#<A:0x00007fe5036922e8 @name="c">,
#<A:0x00007fe5036922c0 @name="d">,
#<A:0x00007fe503692298 @name="e">,
#<A:0x00007fe503692270 @name="f">,
#<A:0x00007fe503692248 @name="g">,
#<A:0x00007fe503692220 @name="h">,
#<A:0x00007fe5036921f8 @name="i">,
#<A:0x00007fe5036921d0 @name="j">,
#<A:0x00007fe5036921a8 @name="k">,
#<A:0x00007fe503692180 @name="l">,
#<A:0x00007fe5035732e0 @name="a">,
#<A:0x00007fe5035732b8 @name="b">,
#<A:0x00007fe503573290 @name="c">,
#<A:0x00007fe503573268 @name="d">,
#<A:0x00007fe503573240 @name="e">,
#<A:0x00007fe503573218 @name="f">,
#<A:0x00007fe5035731f0 @name="g">,
#<A:0x00007fe5035731c8 @name="h">,
#<A:0x00007fe5035731a0 @name="i">,
#<A:0x00007fe503573178 @name="j">,
#<A:0x00007fe503573150 @name="k">,
#<A:0x00007fe503573128 @name="l">]
as[0..7] | bs[0..7]
=>
[#<A:0x00007fe503692388 @name="a">,
#<A:0x00007fe503692310 @name="b">,
#<A:0x00007fe5036922e8 @name="c">,
#<A:0x00007fe5036922c0 @name="d">,
#<A:0x00007fe503692298 @name="e">,
#<A:0x00007fe503692270 @name="f">,
#<A:0x00007fe503692248 @name="g">,
#<A:0x00007fe503692220 @name="h">]
解決策
両方の eql を実装する必要がありますか?およびハッシュメソッドは、Object#eql? に関する @engineersmnky のコメントに従っており、その eql?インスタンスのハッシュが同じであることを期待します
class A
attr_accessor :name
def initialize(name)
@name = name
end
def eql?(other)
other.name.eql?(@name)
end
def hash
[@name].hash
end
end
#declare inclusive range from 'a' to 'm'
names = 'a'..'m'
as = names.map { |name| A.new(name) }
bs = names.map { |name| A.new(name) }
as | bs
出力:
[#<A:0x0000558a74860020 @name="a">,
#<A:0x0000558a7485bf98 @name="b">,
#<A:0x0000558a7485bf70 @name="c">,
#<A:0x0000558a7485bf48 @name="d">,
#<A:0x0000558a7485bf20 @name="e">,
#<A:0x0000558a7485bef8 @name="f">,
#<A:0x0000558a7485bed0 @name="g">,
#<A:0x0000558a7485bea8 @name="h">,
#<A:0x0000558a7485bd90 @name="i">,
#<A:0x0000558a7485bd40 @name="j">,
#<A:0x0000558a7485bd18 @name="k">,
#<A:0x0000558a7485bcf0 @name="l">,
#<A:0x0000558a7485bcc8 @name="m">]