1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* hash.c (rb_hash_eql): new method to be used by Hash.

* hash.c (rb_hash_hash): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10993 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2006-09-22 08:36:02 +00:00
parent 51281b961b
commit 70360efac3
3 changed files with 90 additions and 14 deletions

View file

@ -1,3 +1,9 @@
Fri Sep 22 17:33:29 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* hash.c (rb_hash_eql): new method to be used by Hash.
* hash.c (rb_hash_hash): ditto.
Fri Sep 22 06:53:22 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* bignum.c (rb_big_hash): use rb_memhash().

84
hash.c
View file

@ -1303,6 +1303,23 @@ struct equal_data {
st_table *tbl;
};
static int
eql_i(VALUE key, VALUE val1, struct equal_data *data)
{
VALUE val2;
if (key == Qundef) return ST_CONTINUE;
if (!st_lookup(data->tbl, key, &val2)) {
data->result = Qfalse;
return ST_STOP;
}
if (!rb_eql(val1, val2)) {
data->result = Qfalse;
return ST_STOP;
}
return ST_CONTINUE;
}
static int
equal_i(VALUE key, VALUE val1, struct equal_data *data)
{
@ -1321,7 +1338,7 @@ equal_i(VALUE key, VALUE val1, struct equal_data *data)
}
static VALUE
hash_equal(VALUE hash1, VALUE hash2, int eql /* compare default value if true */)
hash_equal(VALUE hash1, VALUE hash2, int eql)
{
struct equal_data data;
@ -1334,15 +1351,15 @@ hash_equal(VALUE hash1, VALUE hash2, int eql /* compare default value if true */
}
if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)
return Qfalse;
if (eql) {
if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) &&
FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
return Qfalse;
}
#if 0
if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) &&
FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
return Qfalse;
#endif
data.tbl = RHASH(hash2)->tbl;
data.result = Qtrue;
rb_hash_foreach(hash1, equal_i, (st_data_t)&data);
rb_hash_foreach(hash1, eql ? eql_i : equal_i, (st_data_t)&data);
return data.result;
}
@ -1372,6 +1389,57 @@ rb_hash_equal(VALUE hash1, VALUE hash2)
return hash_equal(hash1, hash2, Qfalse);
}
/*
* call-seq:
* hash.eql?(other) -> true or false
*
* Returns <code>true</code> if <i>hash</i> and <i>other</i> are
* both hashes with the same content.
*/
static VALUE
rb_hash_eql(VALUE hash1, VALUE hash2)
{
return hash_equal(hash1, hash2, Qfalse);
}
static int
hash_i(VALUE key, VALUE val, int *hval)
{
if (key == Qundef) return ST_CONTINUE;
*hval ^= rb_hash(key);
*hval ^= rb_hash(val);
return ST_CONTINUE;
}
static VALUE
recursive_hash(VALUE hash, VALUE dummy, int recur)
{
int hval;
VALUE n;
if (recur) {
return LONG2FIX(0);
}
hval = RHASH(hash)->tbl->num_entries;
rb_hash_foreach(hash, hash_i, (st_data_t)&hval);
return INT2FIX(hval);
}
/*
* call-seq:
* array.hash -> fixnum
*
* Compute a hash-code for this array. Two arrays with the same content
* will have the same hash code (and will compare using <code>eql?</code>).
*/
static VALUE
rb_hash_hash(VALUE hash)
{
return rb_exec_recursive(recursive_hash, hash, 0);
}
static int
rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
{
@ -2330,6 +2398,8 @@ Init_Hash(void)
rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
rb_define_method(rb_cHash,"hash", rb_hash_hash, 0);
rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1);
rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1);
rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
rb_define_method(rb_cHash,"store", rb_hash_aset, 2);

View file

@ -76,13 +76,13 @@ rb_eql(VALUE obj1, VALUE obj2)
* object as <code>b</code>).
*
* The <code>eql?</code> method returns <code>true</code> if
<i>obj</i> and <i>anObject</i> have the
* same value. Used by <code>Hash</code> to test members for equality.
* For objects of class <code>Object</code>, <code>eql?</code> is
* synonymous with <code>==</code>. Subclasses normally continue this
* tradition, but there are exceptions. <code>Numeric</code> types, for
* example, perform type conversion across <code>==</code>, but not
* across <code>eql?</code>, so:
* <i>obj</i> and <i>anObject</i> have the same value. Used by
* <code>Hash</code> to test members for equality. For objects of
* class <code>Object</code>, <code>eql?</code> is synonymous with
* <code>==</code>. Subclasses normally continue this tradition, but
* there are exceptions. <code>Numeric</code> types, for example,
* perform type conversion across <code>==</code>, but not across
* <code>eql?</code>, so:
*
* 1 == 1.0 #=> true
* 1.eql? 1.0 #=> false