From 30327ee727a231745d9ed7d24e050beb454bd634 Mon Sep 17 00:00:00 2001 From: Abhilash Reddy Date: Wed, 10 Oct 2018 22:00:19 +0530 Subject: [PATCH 1/5] Recursively converting child hash attributes to OpenStruct. --- lib/ostruct.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index 67ba043..9156513 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -93,7 +93,7 @@ def initialize(hash=nil) if hash hash.each_pair do |k, v| k = k.to_sym - @table[k] = v + @table[k] = v.is_a?(Hash) ? OpenStruct.new(v) : v end end end From 252ff50ad2f3c2b6f9d3d19a9aa4815f2dcf3614 Mon Sep 17 00:00:00 2001 From: Abhilash Reddy Date: Wed, 10 Oct 2018 22:43:06 +0530 Subject: [PATCH 2/5] Handling hash attributes in method_missing --- lib/ostruct.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index 9156513..08354d4 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -202,7 +202,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)] = args[0].is_a?(Hash) ? OpenStruct.new(args[0]) : args[0] elsif len == 0 # and /\A[a-z_]\w*\z/ =~ mid # if @table.key?(mid) new_ostruct_member!(mid) unless frozen? From 50ed63ebff15dec3acacf626bb64b8d8338579d9 Mon Sep 17 00:00:00 2001 From: Abhilash Reddy Date: Mon, 15 Oct 2018 19:18:53 +0530 Subject: [PATCH 3/5] Make recursiveness optional. Default is set to false. --- lib/ostruct.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index 08354d4..5a14d93 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -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 @@ -88,12 +89,13 @@ class OpenStruct # # data # => # # - def initialize(hash=nil) + def initialize(hash=nil, is_recursive=false) @table = {} + @recursive = is_recursive if hash hash.each_pair do |k, v| k = k.to_sym - @table[k] = v.is_a?(Hash) ? OpenStruct.new(v) : v + @table[k] = (recursive && v.is_a?(Hash)) ? OpenStruct.new(v,true) : v end end end @@ -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].is_a?(Hash) ? OpenStruct.new(args[0]) : 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? From 852f0e3fa00d9fe148047df2f2d629d042509be0 Mon Sep 17 00:00:00 2001 From: Abhilash Reddy Date: Tue, 16 Oct 2018 08:30:29 +0530 Subject: [PATCH 4/5] Removed attr_reader for recursive; Also using respond_to?(:to_hash) instead of is_a?(Hash) --- lib/ostruct.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index 5a14d93..3a5b6c3 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -73,8 +73,6 @@ # 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 # object will have no attributes. @@ -95,7 +93,7 @@ def initialize(hash=nil, is_recursive=false) if hash hash.each_pair do |k, v| k = k.to_sym - @table[k] = (recursive && v.is_a?(Hash)) ? OpenStruct.new(v,true) : v + @table[k] = (@recursive && v.respond_to?(:to_hash)) ? OpenStruct.new(v,true) : v end end end @@ -204,7 +202,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)] = (recursive && args[0].is_a?(Hash)) ? OpenStruct.new(args[0],true) : args[0] + modifiable?[new_ostruct_member!(mname)] = (@recursive && args[0].respond_to?(:to_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? From 388869cc5d816362fb95d954e9897fbc5e7b4d79 Mon Sep 17 00:00:00 2001 From: Abhilash Reddy Date: Tue, 16 Oct 2018 13:48:12 +0530 Subject: [PATCH 5/5] Passing options as an argument to initializer instead of is_recursive, --- lib/ostruct.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index 3a5b6c3..e60abc6 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -87,13 +87,14 @@ class OpenStruct # # data # => # # - def initialize(hash=nil, is_recursive=false) + def initialize(hash=nil, options={recursive: true}) @table = {} - @recursive = is_recursive + @recursive = options.fetch(:recursive, false) + puts @recursive 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 + @table[k] = (@recursive && v.respond_to?(:to_hash)) ? OpenStruct.new(v, {recursive: true}) : v end end end @@ -202,7 +203,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)] = (@recursive && args[0].respond_to?(:to_hash)) ? OpenStruct.new(args[0],true) : args[0] + modifiable?[new_ostruct_member!(mname)] = (@recursive && args[0].respond_to?(:to_hash)) ? OpenStruct.new(args[0], {recursive: true}) : args[0] elsif len == 0 # and /\A[a-z_]\w*\z/ =~ mid # if @table.key?(mid) new_ostruct_member!(mid) unless frozen?