[#44725] Set[Set[1]]==Set[Set[1]] は偽? — "5.5" <5.5@...>

5.5 です。

22 messages 2008/03/04

[#44782] $stdin.rewind が exec した子プロセスに伝わらない? — SATOH Fumiyasu <fumiyas@...>

さとうふみやす @ OSS テクノロジです。

11 messages 2008/03/17
[#44783] Re: $stdin.rewind が exec した子プロセスに伝わらない? — Kazuhiro NISHIYAMA <zn@...> 2008/03/17

西山和広です。

[ruby-list:44727] Re: Set[Set[1]]==Set[Set[1]] は偽?

From: Tietew <tietew+ruby-list@...>
Date: 2008-03-05 02:10:53 UTC
List: ruby-list #44727
On Tue, 4 Mar 2008 23:21:14 +0900
In article <47CD5AE2.2060007@moji.gr.jp>
[[ruby-list:44725] Set[Set[1]]==Set[Set[1]]  は偽?]
"5.5" <5.5@moji.gr.jp> wrote:

> 5.5 です。
> 
> set ライブラリについての疑問です。
> 
> Set[Set[1]]==Set[Set[1]] は false を返します。
> これは,Set が要素の同一性の判定に eql? を使っており,Set#eql?
> はハッシュ値の一致を見ているからですよね。

eql? は、ハッシュのキーとして一致するかどうかを返すメソッドですから、
Set(というか Hash)が eql? を使うのは正しいです。

問題はそこではなく、Set[1].hash が毎回違う値を返すことなのですが、何故な
のかというと、Hash がもともとハッシュのキーとして使われることを想定して
いないからです。

irb(main):001:0> {1=>true}.eql?({1=>true})
=> false
irb(main):002:0> [1].eql?([1])
=> true

直したかったら、以下で直ります。
ただし、遅くなります。

require 'set'
class Set
  def hash
    @hash.keys.hash
  end
  def eql?(o)
    o.is_a?(Set) && @hash.keys.eql?(o.instance_variable_get(:@hash).keys)
  end
end



-- 
Tietew <tietew@tietew.net>
Blog: http://www.tietew.jp/
PGP: 26CB 71BB B595 09C4 0153  81C4 773C 963A D51B 8CAA


In This Thread