From 2b5a14bf7c96fcda9ff6cd9bbdd83d9294a0d354 Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 7 May 2004 08:48:30 +0000 Subject: * eval.c (rb_eval): too many line trace call. (ruby-bugs PR#1320) * numeric.c (flo_to_s): tweak output string based to preserve decimal point and to remove trailing zeros. [ruby-talk:97891] * string.c (rb_str_index_m): use unsigned comparison for T_FIXNUM search. [ruby-talk:97342] * hash.c (rb_hash_equal): returns true if two hashes have same set of key-value set. [ruby-talk:97559] * hash.c (rb_hash_eql): returns true if two hashes are equal and have same default values. * string.c (rb_str_equal): always returns true or false, never returns nil. [ruby-dev:23404] * io.c (rb_io_reopen): should use rb_io_check_io(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6263 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- hash.c | 63 +++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 18 deletions(-) (limited to 'hash.c') diff --git a/hash.c b/hash.c index fc2897668c..9d1c5d04bc 100644 --- a/hash.c +++ b/hash.c @@ -1392,6 +1392,35 @@ equal_i(key, val1, data) return ST_CONTINUE; } +static VALUE +hash_equal(hash1, hash2, eql) + VALUE hash1, hash2; + int eql; /* compare default value if true */ +{ + struct equal_data data; + + if (hash1 == hash2) return Qtrue; + if (TYPE(hash2) != T_HASH) { + if (!rb_respond_to(hash2, rb_intern("to_hash"))) { + return Qfalse; + } + return rb_equal(hash2, hash1); + } + 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; + } + + data.tbl = RHASH(hash2)->tbl; + data.result = Qtrue; + st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data); + + return data.result; +} + /* * call-seq: * hsh == other_hash => true or false @@ -1415,26 +1444,23 @@ static VALUE rb_hash_equal(hash1, hash2) VALUE hash1, hash2; { - struct equal_data data; - - if (hash1 == hash2) return Qtrue; - if (TYPE(hash2) != T_HASH) { - if (!rb_respond_to(hash2, rb_intern("to_hash"))) { - return Qfalse; - } - return rb_equal(hash2, hash1); - } - if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries) - return Qfalse; - if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) && - FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT))) - return Qfalse; + return hash_equal(hash1, hash2, Qfalse); +} - data.tbl = RHASH(hash2)->tbl; - data.result = Qtrue; - st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data); +/* + * call-seq: + * hsh.eql?(other_hash) => true or false + * + * Returns true if two hashes are equal, i.e they have same key-value set, + * and same default values. + * + */ - return data.result; +static VALUE +rb_hash_eql(hash1, hash2) + VALUE hash1, hash2; +{ + return hash_equal(hash1, hash2, Qtrue); } static int @@ -2368,6 +2394,7 @@ Init_Hash() rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0); rb_define_method(rb_cHash,"==", rb_hash_equal, 1); + rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1); rb_define_method(rb_cHash,"[]", rb_hash_aref, 1); rb_define_method(rb_cHash,"fetch", rb_hash_fetch, -1); rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2); -- cgit v1.2.3