proposal Hash eql? , ==, ===

1 view
Skip to first unread message

wal...@mwsewall.com

unread,
Apr 16, 2004, 9:12:45 AM4/16/04
to
(Note: I sent a similar email last night in response to Matz, but
did not see it. I apologize if this is basically a duplicate.)


Hash#== should be for would be content equals and not
content and default value/proc equal. I think that most common case
for == would be content equality.

Hash#=== as Nobu pointed out === would make more sense to be a
membership test, i.e., alias for Hash#key?.

Hash.eql? should be content equal and default value/block (i.e what
the current == is now). There is some precedence for this in Numeric
where 1 == 1.0 is true but 1.eql?(1.0) is false. I see this as being
very similar circumstance.

Thanks for listening,


Walt

*****************************************************
Walter Szewelanczyk
IS Director
M.W. Sewall & CO. email : wal...@mwsewall.com
259 Front St. Phone : (207) 442-7994 x 128
Bath, ME 04530 Fax : (207) 443-6284
*****************************************************

Yukihiro Matsumoto

unread,
Apr 19, 2004, 4:46:40 AM4/19/04
to
Hi,

In message "proposal Hash eql? , ==, ==="

|Hash#== should be for would be content equals and not
|content and default value/proc equal. I think that most common case
|for == would be content equality.
|
|Hash#=== as Nobu pointed out === would make more sense to be a
|membership test, i.e., alias for Hash#key?.
|
|Hash.eql? should be content equal and default value/block (i.e what
|the current == is now). There is some precedence for this in Numeric
|where 1 == 1.0 is true but 1.eql?(1.0) is false. I see this as being
|very similar circumstance.

I agree with both Hash#== and Hash#eql? But I'm not very positive
about making Hash#=== a membership test. Some usage of "===" are
membership, for example, Array and Class, but they are not general
consensus. I'm not sure how much useful that making === membership.

matz.


Elias Athanasopoulos

unread,
Apr 19, 2004, 6:32:07 AM4/19/04
to
> I agree with both Hash#== and Hash#eql? But I'm not very positive

elathan@testbed:~/hacking/ruby> cat ../test.rb

h1 = Hash.new(42)
h1["a"] = 1
h1["b"] = 2

h2 = { "a" => 1, "b" => 2 }

puts h1 == h2
puts h1.eql?(h2)
elathan@testbed:~/hacking/ruby> ./ruby ../test.rb
true
false


--- hash.c.orig 2004-04-19 12:08:24.000000000 +0300
+++ hash.c 2004-04-19 12:21:06.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.eql? other_hash => true or false
+ *
+ * Strict 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 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.eql? h2 #=> false
+ * h2.eql? h3 #=> true
+ * h3.eql? 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;
@@ -2365,6 +2407,8 @@
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_strict_equal, 1);
+ rb_define_method(rb_cHash,"==", rb_hash_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);

Reply all
Reply to author
Forward
0 new messages