From b4300d25c941475db902ed2dc667ac23d36be992 Mon Sep 17 00:00:00 2001 From: marcandre Date: Sun, 28 Oct 2012 21:19:15 +0000 Subject: * lib/ostruct.rb: Add OpenStruct#eql? and OpenStruct#hash [ruby-core:42651] [Bug #6029] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- NEWS | 5 +++++ lib/ostruct.rb | 21 +++++++++++++++++++-- test/ostruct/test_ostruct.rb | 10 ++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index f76f676728..beda22536b 100644 --- a/NEWS +++ b/NEWS @@ -119,6 +119,8 @@ with all sufficient information, see the ChangeLog file. * ostruct * new methods: * OpenStruct#each_pair + * OpenStruct#eql? + * OpenStruct#hash * OpenStruct#to_h converts the struct to a hash. * pathname @@ -213,3 +215,6 @@ with all sufficient information, see the ChangeLog file. * Dir.mktmpdir in lib/tmpdir.rb See above. + + * OpenStruct new methods can conflict with custom attributes named + "each_pair", "eql?", "hash" or "to_h". diff --git a/lib/ostruct.rb b/lib/ostruct.rb index e22fca3e46..c00039016a 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -241,7 +241,24 @@ class OpenStruct # equal. # def ==(other) - return false unless(other.kind_of?(OpenStruct)) - return @table == other.table + return false unless other.kind_of?(OpenStruct) + @table == other.table + end + + # + # Compares this object and +other+ for equality. An OpenStruct is eql? to + # +other+ when +other+ is an OpenStruct and the two objects' Hash tables are + # eql?. + # + def eql?(other) + return false unless other.kind_of?(OpenStruct) + @table.eql?(other.table) + end + + # Compute a hash-code for this OpenStruct. + # Two hashes with the same content will have the same hash code + # (and will be eql?). + def hash + @table.hash end end diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb index 9b125fc055..a7cfbe994f 100644 --- a/test/ostruct/test_ostruct.rb +++ b/test/ostruct/test_ostruct.rb @@ -92,4 +92,14 @@ class TC_OpenStruct < Test::Unit::TestCase assert_equal '#:each_pair>', os.each_pair.inspect assert_equal [[:name, "John Smith"], [:age, 70], [:pension, 300]], os.each_pair.to_a end + + def test_eql_and_hash + os1 = OpenStruct.new age: 70 + os2 = OpenStruct.new age: 70.0 + assert_equal os1, os2 + assert_equal false, os1.eql?(os2) + assert_not_equal os1.hash, os2.hash + assert_equal true, os1.eql?(os1.dup) + assert_equal os1.hash, os1.dup.hash + end end -- cgit v1.2.3