7

Ruby の「ハッシュ」メソッドに問題があります: http://apidock.com/ruby/v1_8_7_330/Hash/hash

これを使用して、同じコンテンツを持つ 2 つの異なるオブジェクトを比較し、データベース オブジェクトと同じ属性を持つ新しい要素の間の衝突を見つけます。

どうやら長い間 (1 年以上) 動作していたようですが、開発用コンピューターで突然動作しなくなりました。

Railsコンソールでこれを試すと:

a = {:a => 'a', :b=>'b'}
b = {:a => 'a', :b=>'b'}
a.hash
b.hash

-3820017043059270405同じコンソールでa.hash と b.hash ( ) の両方で同じ値を取得します。問題は、別のコンソールに変更すると、最初のコンソールとは異なる値が返されることです ( -1865824882785682267)。

これまでと同じハッシュを返すべきではありませんか?

前もって感謝します。

編集:ree 1.8.7バージョンのため、本番環境でうまく機能しました。

4

2 に答える 2

7

いいえ、そうすべきではありません!

さまざまな Ruby 実装 (jRuby、Rubinius、MRI 1.8.x、MRI 1.9.x など) は、さまざまな方法でハッシュを生成しています。たとえば、一部のオブジェクト (所有しているクラスや Hash インスタンスなど) の場合、ランタイムは、このオブジェクトの作成中に uniq およびランダム ID を割り当てます。私が間違っていなければ、MRI タイトはメモリ アドレスに基づくハッシュで動作します: http://rxr.whitequark.org/mri/source/gc.c?v=1.8.7-p370#2111

そのため、コードを実行するたびに毎回同じランダム値または同じメモリ アドレスが使用されることを保証することはできません。

また、Ruby 内部では apidock の代わりに ruby​​-doc を使用することをお勧めします: http://ruby-doc.org/core-2.0/Object.html#method-i-hash

オブジェクトのハッシュ値は、Ruby の呼び出しまたは実装間で同一ではない場合があります。Ruby の呼び出しと実装全体で安定した識別子が必要な場合は、カスタム メソッドで生成する必要があります。

それがあなたを助けることを願っています!

于 2013-03-15T11:57:10.950 に答える
2

出典: http://ruby-doc.org/core-2.0/Object.html#method-i-hash

オブジェクトのハッシュ値は、Ruby の呼び出しまたは実装間で同一ではない場合があります。Ruby の呼び出しと実装全体で安定した識別子が必要な場合は、カスタム メソッドで生成する必要があります。

これは Ruby 2.0 のドキュメントですが、これはしばらく前からあったと思います。つまり、Ruby オブジェクトが .eql を使用して同等であることが一般に保証されていませんか? 異なる Ruby プロセスで計算された同じハッシュ値を持つことになります。

Hash.hash を呼び出すと、ハッシュ オブジェクトのキーと値として使用されるオブジェクトから計算されたハッシュ値の組み合わせが返されるため、同じドキュメントの対象になると理解しています。

于 2013-03-15T11:43:41.153 に答える