Class: RecursiveOpenStruct
- Inherits:
-
OpenStruct
- Object
- OpenStruct
- RecursiveOpenStruct
- Includes:
- DebugInspect, Ruby19Backport
- Defined in:
- lib/recursive_open_struct.rb,
lib/recursive_open_struct/version.rb
Defined Under Namespace
Modules: DebugInspect, Ruby19Backport Classes: DeepDup
Constant Summary collapse
- VERSION =
"0.6.5"
Instance Method Summary collapse
- #[](name) ⇒ Object
- #delete_field(name) ⇒ Object
-
#initialize(hash = nil, args = {}) ⇒ RecursiveOpenStruct
constructor
A new instance of RecursiveOpenStruct.
- #initialize_copy(orig) ⇒ Object
- #new_ostruct_member(name) ⇒ Object
-
#recurse_over_array(array) ⇒ Object
TODO: Make me private if/when we do an API-breaking change release.
- #to_h ⇒ Object (also: #to_hash)
Methods included from DebugInspect
#debug_inspect, #display_recursive_open_struct
Methods included from Ruby19Backport
#[]=, #each_pair, #eql?, #hash
Constructor Details
#initialize(hash = nil, args = {}) ⇒ RecursiveOpenStruct
Returns a new instance of RecursiveOpenStruct.
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/recursive_open_struct.rb', line 12 def initialize(hash=nil, args={}) hash ||= {} @recurse_over_arrays = args.fetch(:recurse_over_arrays, false) @deep_dup = DeepDup.new(recurse_over_arrays: @recurse_over_arrays) @table = args.fetch(:mutate_input_hash, false) ? hash : @deep_dup.call(hash) @table && @table.each_key { |k| new_ostruct_member(k) } @sub_elements = {} end |
Instance Method Details
#[](name) ⇒ Object
38 39 40 |
# File 'lib/recursive_open_struct.rb', line 38 def [](name) send name end |
#delete_field(name) ⇒ Object
84 85 86 87 88 89 |
# File 'lib/recursive_open_struct.rb', line 84 def delete_field(name) sym = _get_key_from_table_(name) singleton_class.__send__(:remove_method, sym, "#{sym}=") @sub_elements.delete sym @table.delete sym end |
#initialize_copy(orig) ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/recursive_open_struct.rb', line 23 def initialize_copy(orig) super # deep copy the table to separate the two objects @table = @deep_dup.call(orig.instance_variable_get(:@table)) # Forget any memoized sub-elements @sub_elements = {} end |
#new_ostruct_member(name) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/recursive_open_struct.rb', line 42 def new_ostruct_member(name) key_name = _get_key_from_table_ name unless self.respond_to?(name) class << self; self; end.class_eval do define_method(name) do v = @table[key_name] if v.is_a?(Hash) @sub_elements[key_name] ||= self.class.new( v, :recurse_over_arrays => @recurse_over_arrays, :mutate_input_hash => true ) elsif v.is_a?(Array) and @recurse_over_arrays @sub_elements[key_name] ||= recurse_over_array(v) @sub_elements[key_name] = recurse_over_array(@sub_elements[key_name]) else v end end define_method("#{name}=") do |x| @sub_elements.delete(key_name) modifiable[key_name] = x end define_method("#{name}_as_a_hash") { @table[key_name] } end end key_name end |
#recurse_over_array(array) ⇒ Object
TODO: Make me private if/when we do an API-breaking change release
72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/recursive_open_struct.rb', line 72 def recurse_over_array(array) array.map do |a| if a.is_a? Hash self.class.new(a, :recurse_over_arrays => true, :mutate_input_hash => true) elsif a.is_a? Array recurse_over_array a else a end end end |
#to_h ⇒ Object Also known as: to_hash
32 33 34 |
# File 'lib/recursive_open_struct.rb', line 32 def to_h @deep_dup.call(@table) end |