8000 lib/ostruct.rb: fix and enhance OpenStruct by trans · Pull Request #95 · ruby/ruby · GitHub
[go: up one dir, main page]

Skip to content

lib/ostruct.rb: fix and enhance OpenStruct #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 60 additions & 1 deletion lib/ostruct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,11 @@ class << self; self; end.class_eval do
end
name
end
protected :new_ostruct_member

#
# Missing methods can be used to set and read new OpenStruct members.
#
def method_missing(mid, *args) # :nodoc:
mname = mid.id2name
len = args.length
Expand Down Expand Up @@ -231,7 +235,62 @@ def inspect
# equal.
#
def ==(other)
return false unless(other.kind_of?(OpenStruct))
return false unless OpenStruct === other
return @table == other.table
end

#
# Compares this object and +other+ for strict equality. An OpenStruct is
# equal to +other+ when +other+ is an OpenStruct and the two object's Hash
# tables are equal.
#
def eql?(other)
return false unless OpenStruct === other
return @table == other.table
end

#
# Access a value in the OpenStruct by key, like a Hash.
# This increases OpenStruct's "duckiness".
#
# o = OpenStruct.new
# o.t = 4
# o['t'] #=> 4
#
def [](name)
@table[name.to_sym]
end

#
# Set a value in the OpenStruct by key, like a Hash.
#
# o = OpenStruct.new
# o['t'] = 4
# o.t #=> 4
#
def []=(name, value)
modifiable[new_ostruct_member(name)] = value
end

#
# Convert OpenStruct to hash. This method duplicates the
# underlying table and returns it.
#
# o = OpenStruct.new('a'=>1, 'b'=>2)
# o.to_h #=> {:a=>1, :b=>2}
#
def to_h
@table.dup
end

#
# Merge +hash+ into underlying OpenStruct table. The keys
# of the hash must respond to #to_sym.
#
def merge!(hash)
for name,value in hash
modifiable[new_ostruct_member(name)] = value
end
end

end
26 changes: 21 additions & 5 deletions test/ostruct/test_ostruct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ def test_equality
assert_not_equal(o1, o2)
end

def test_eql
o1 = OpenStruct.new(:a=>'a')
o2 = OpenStruct.new(:a=>'a')
o3 = OpenStruct.new(:a=>'b')
assert o1.eql?(o2)
assert !o1.eql?(o3)
end

def test_inspect
foo = OpenStruct.new
assert_equal("#<OpenStruct>", foo.inspect)
Expand Down Expand Up @@ -62,14 +70,22 @@ def test_delete_field
assert_not_respond_to(o, :a=, bug)
end

def test_method_missing_handles_square_bracket_equals
def test_square_bracket_equals
o = OpenStruct.new
assert_raise(NoMethodError) { o[:foo] = :bar }
o[:foo] = 40
assert_equal(o[:foo], 40)
end

def test_method_missing_handles_square_brackets
o = OpenStruct.new
assert_raise(NoMethodError) { o[:foo] }
def test_square_brackets
o = OpenStruct.new(:foo=>4)
assert_equal(o[:foo], 4)
end

def test_merge
o = OpenStruct.new(:foo=>4)
o.merge!(:bar=>5)
assert_equal(o.bar, 5)
assert_equal(o.foo, 4)
end

end
0