Class: RecursiveOpenStruct

Inherits:
OpenStruct
  • Object
show all
Includes:
DebugInspect
Defined in:
lib/recursive_open_struct.rb,
lib/recursive_open_struct/version.rb

Defined Under Namespace

Modules: DebugInspect Classes: DeepDup

Constant Summary collapse

VERSION =
"0.6.0"

Instance Method Summary collapse

Methods included from DebugInspect

#debug_inspect, #display_recursive_open_struct

Constructor Details

#initialize(hash = nil, args = {}) ⇒ RecursiveOpenStruct

Returns a new instance of RecursiveOpenStruct.



10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/recursive_open_struct.rb', line 10

def initialize(hash=nil, args={})
  @recurse_over_arrays = args.fetch(:recurse_over_arrays, false)
  mutate_input_hash = args.fetch(:mutate_input_hash, false)

  unless mutate_input_hash
    hash = DeepDup.new(recurse_over_arrays: @recurse_over_arrays).call(hash)
  end

  super(hash)

  @sub_elements = {}
end

Instance Method Details

#[](name) ⇒ Object



37
38
39
# File 'lib/recursive_open_struct.rb', line 37

def [](name)
  send name
end

#new_ostruct_member(name) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/recursive_open_struct.rb', line 41

def new_ostruct_member(name)
  name = name.to_sym
  unless self.respond_to?(name)
    class << self; self; end.class_eval do
      define_method(name) do
        v = @table[name]
        if v.is_a?(Hash)
          @sub_elements[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[name] ||= recurse_over_array(v)
        else
          v
        end
      end
      define_method("#{name}=") { |x| modifiable[name] = x }
      define_method("#{name}_as_a_hash") { @table[name] }
    end
  end
  name
end

#recurse_over_array(array) ⇒ Object

TODO: Make me private if/when we do an API-breaking change release



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/recursive_open_struct.rb', line 65

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_hObject Also known as: to_hash



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/recursive_open_struct.rb', line 23

def to_h
  @table.dup.update(@sub_elements) do |k, oldval, newval|
    if newval.kind_of?(self.class)
      newval.to_h
    elsif newval.kind_of?(Array)
      newval.map { |a| a.kind_of?(self.class) ? a.to_h : a }
    else
      raise "Cached value of unsupported type: #{newval.inspect}"
    end
  end
end