Skip to content
Open
Changes from 3 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
8 changes: 5 additions & 3 deletions lib/ostruct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
# of these properties compared to using a Hash or a Struct.
#
class OpenStruct
attr_reader :recursive

#
# Creates a new OpenStruct object. By default, the resulting OpenStruct
Expand All @@ -88,12 +89,13 @@ class OpenStruct
#
# data # => #<OpenStruct country="Australia", capital="Canberra">
#
def initialize(hash=nil)
def initialize(hash=nil, is_recursive=false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be more readable to use a keyword argument I'd say

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated! Thanks :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we use keyword argument the below test will fail:

def test_accessor_defines_method
    os = OpenStruct.new(foo: 42)
    assert os.respond_to? :foo
    assert_equal([], os.singleton_methods)
    assert_equal(42, os.foo)
    assert_equal([:foo, :foo=], os.singleton_methods.sort)
end

But for better readability I changed the constructor to this:

def initialize(hash=nil, options={recursive: false})
    @table = {}
    @recursive = options.fetch(:recursive, false)
    if hash
      hash.each_pair do |k, v|
        k = k.to_sym
        @table[k] = (@recursive && v.respond_to?(:to_hash)) ? OpenStruct.new(v,true) : v
      end
    end
end

@table = {}
@recursive = is_recursive
if hash
hash.each_pair do |k, v|
k = k.to_sym
@table[k] = v
@table[k] = (recursive && v.is_a?(Hash)) ? OpenStruct.new(v,true) : v
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I pointed out, best use respond_to?(:to_hash) instead of is_a?(Hash)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry missed that. Updated the code!

end
end
end
Expand Down Expand Up @@ -202,7 +204,7 @@ def method_missing(mid, *args) # :nodoc:
if len != 1
raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
end
modifiable?[new_ostruct_member!(mname)] = args[0]
modifiable?[new_ostruct_member!(mname)] = (recursive && args[0].is_a?(Hash)) ? OpenStruct.new(args[0],true) : args[0]
elsif len == 0 # and /\A[a-z_]\w*\z/ =~ mid #
if @table.key?(mid)
new_ostruct_member!(mid) unless frozen?
Expand Down