On Fri, Apr 16, 2004 at 02:30:02AM +0900,
wrote:
>
> > On Fri, Apr 16, 2004 at 02:04:10AM +0900, wrote: >
> > Ok, > > ALthough the docs don't mention it, Hash comparison using ==
> > checks > not only the key value pairs, but also the default value /
> > default > procs. > > So how does one compare 2 hashes key-value pairs.
> > I can see that it
> >
> > I can contribute a patch to:
> >
> > * Change '==' method to compare only key-value pairs.
> > * Add Hash#=== method to act like current Hash#==
> >
> > Comments?
> >
>
> Personally, I like the idea. You get my vote!
I will add a ChangeLog entry if it is accepted.
elathan@velka:~/hacking/ruby> cat ../test.rb
h1 = { "a" => 1, "b" => 2}
h2 = Hash.new(2)
h2["a"] = 1
h2["b"] = 2
puts h1 == h2
puts h1 === h2
elathan@velka:~/hacking/ruby> ./ruby ../test.rb
true
false
Enjoy,
--
University of Athens I bet the human brain
Physics Department is a kludge --Marvin Minsky
--- /home/elathan/hacking/ruby/hash.c.orig 2004-04-15 04:46:29.000000000 +0300
+++ /home/elathan/hacking/ruby/hash.c 2004-04-15 04:52:39.000000000 +0300
@@ -1425,6 +1425,48 @@
}
if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)
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
+ *
+ * Equality---Two hashes are strictly equal if they each contain the same number
+ * of keys and if each key-value pair is equal to (according to
+ * <code>Object#==</code>) the corresponding elements in the other
+ * hash. Both hashes must have also equal default values/procs.
+ *
+ * h1 = { "a" => 1, "c" => 2 }
+ * h2 = { 7 => 35, "c" => 2, "a" => 1 }
+ * h3 = { "a" => 1, "c" => 2, 7 => 35 }
+ * h4 = { "a" => 1, "d" => 2, "f" => 35 }
+ * h1 === h2 #=> false
+ * h2 === h3 #=> true
+ * h3 === h4 #=> false
+ *
+ */
+
+static VALUE
+rb_hash_strict_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;
@@ -1435,7 +1477,6 @@
return data.result;
}
-
static int
rb_hash_invert_i(key, value, hash)
VALUE key, value;
@@ -2365,6 +2406,7 @@
rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
+ rb_define_method(rb_cHash,"===", rb_hash_strict_equal, 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);