diff --git a/lib/ostruct.rb b/lib/ostruct.rb index a8763da..e8ab721 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -383,6 +383,32 @@ def delete_field(name, &block) end end + + # Returns +true+ if the given name is a member of this OpenStruct object, +false+ otherwise. + # The given +name+ is converted to a symbol before checking. + # + # require "ostruct" + # person = OpenStruct.new("name" => "John Smith", :age => 70) + # person.include?(:name) # => true + # person.include?("age") # => true + # person.include?(:phone) # => false + # + # This method can be used to test for the presence of a value without creating + # an accessor method if it doesn't exist: + # + # person = OpenStruct.new + # person.name = "John" + # person.include?(:name) # => true + # person.include?(:age) # => false + # person.age # => nil (but creates an accessor) + # person.include?(:age) # => false + # + def include?(name) + @table.has_key?(name.to_sym) + end + alias_method :has_key?, :include? + alias_method :key?, :include? + InspectKey = :__inspect_key__ # :nodoc: # diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb index 616f84d..a31e7d1 100644 --- a/test/ostruct/test_ostruct.rb +++ b/test/ostruct/test_ostruct.rb @@ -439,4 +439,65 @@ def test_performance_warning ) end end + def setup + end + + def test_has_key_alias + o = OpenStruct.new(name: "John Smith", age: 70) + assert_equal o.include?(:name), o.has_key?(:name) + assert_equal o.include?("name"), o.has_key?("name") + assert_equal o.include?(:missing), o.has_key?(:missing) + end + + def test_include_with_symbol + o = OpenStruct.new(name: "John Smith", age: 70, pension: 300) + assert_true o.include?(:name) + assert_true o.include?(:age) + assert_true o.include?(:pension) + assert_false o.include?(:address) + end + + def test_include_with_string + o = OpenStruct.new(name: "John Smith", age: 70, pension: 300) + assert_true o.include?("name") + assert_true o.include?("age") + assert_true o.include?("pension") + assert_false o.include?("address") + end + + def test_include_after_deletion + o = OpenStruct.new(name: "John Smith", age: 70, pension: 300) + o.delete_field(:name) + assert_false o.include?(:name) + end + + def test_include_with_nil_value + o = OpenStruct.new(name: "John Smith", age: 70, pension: 300) + o.pension = nil + assert_true o.include?(:pension) + end + + def test_include_with_new_ostruct + os = OpenStruct.new + assert_false os.include?(:any_key) + end + + def test_include_after_setting_value + o = OpenStruct.new(name: "John Smith", age: 70, pension: 300) + o.phone = "123-456-7890" + assert_true o.include?(:phone) + end + + def test_include_case_sensitivity + o = OpenStruct.new(name: "John Smith", age: 70, pension: 300) + assert_true o.include?(:name) + assert_false o.include?(:Name) + end + + def test_key_alias + o = OpenStruct.new(name: "John Smith", age: 70) + assert_equal o.include?(:name), o.key?(:name) + assert_equal o.include?("name"), o.key?("name") + assert_equal o.include?(:missing), o.key?(:missing) + end end