I've been finding OpenStruct to be very useful lately, and then I discovered
(while testing something) that they can't be effectively compared. I've
included a patch, with a test, to add that functionality. I'm not 100% sure
about the #hash method; this patch was what precipated my earlier question
about the Hash#hash method. Comments are welcome.

If the patch is OK, I can commit it.

Thanks,


Nathaniel

<:((><

Index: lib/ostruct.rb
===================================================================
RCS file: /src/ruby/lib/ostruct.rb,v
retrieving revision 1.7
diff -u -w -r1.7 ostruct.rb
--- lib/ostruct.rb	26 Aug 2003 14:54:51 -0000	1.7
+++ lib/ostruct.rb	24 Sep 2003 01:06:16 -0000
@@ -48,4 +48,13 @@
     end
     str << ">"
   end
+
+  def ==(other)
+    return false unless(other.kind_of?(OpenStruct))
+    return @table == other.instance_eval{@table}
+  end
+
+  def hash
+    @table.keys.hash ^ @table.values.hash
+  end
 end
Index: test/ostruct/test_ostruct.rb
===================================================================
RCS file: test/ostruct/test_ostruct.rb
diff -N test/ostruct/test_ostruct.rb
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test/ostruct/test_ostruct.rb	24 Sep 2003 01:06:16 -0000
@@ -0,0 +1,36 @@
+require 'test/unit'
+require 'ostruct'
+
+class TC_OpenStruct < Test::Unit::TestCase
+  def test_equality
+    o1 = OpenStruct.new
+    o2 = OpenStruct.new
+    assert_equal(o1, o2)
+
+    o1.a = 'a'
+    assert_not_equal(o1, o2)
+
+    o2.a = 'a'
+    assert_equal(o1, o2)
+
+    o1.a = 'b'
+    assert_not_equal(o1, o2)
+
+    o2 = Object.new
+    o2.instance_eval{@table = {:a => 'b'}}
+    assert_not_equal(o1, o2)
+  end
+
+  def test_hash
+    assert_equal(OpenStruct.new.hash, OpenStruct.new.hash)
+    assert_not_equal(OpenStruct.new(:a => 'a').hash, OpenStruct.new.hash)
+    assert_not_equal(OpenStruct.new(:a => 'a').hash, OpenStruct.new(:a => 
b').hash)
+    o1 = OpenStruct.new
+    o1.a = 'a'
+    o1.b = 'b'
+    o2 = OpenStruct.new
+    o2.b = 'b'
+    o2.a = 'a'
+    assert_equal(o1, o2)
+  end
+end