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