Class: Blacklight::NestedOpenStructWithHashAccess

Inherits:
OpenStructWithHashAccess show all
Extended by:
Deprecation
Defined in:
lib/blacklight/nested_open_struct_with_hash_access.rb

Overview

An OpenStruct refinement that converts any hash-keys into additional instances of NestedOpenStructWithHashAccess

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from OpenStructWithHashAccess

#reverse_merge, #sort_by, #sort_by!, #to_h

Constructor Details

#initialize(klass, hash = {}) ⇒ NestedOpenStructWithHashAccess

Returns a new instance of NestedOpenStructWithHashAccess.



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 15

def initialize(klass, hash = {})
  @nested_class = klass
  value = hash.each_with_object({}) do |(k, v), h|
    h[k] = if v.is_a? Hash
             nested_class.new({ key: k.to_sym }.merge(v))
           else
             v
           end
  end

  super value
  set_default_proc!
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(mid, *args, **kwargs, &block) ⇒ Object

Override #method_missing from OpenStruct to ensure the default_proc logic gets triggered.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 92

def method_missing(mid, *args, **kwargs, &block)
  len = args.length

  res = if mid.to_s.end_with?('!')
          m = mid[0...-1].to_sym
          new_ostruct_member!(m)
          @table[m]
        elsif mid.to_s.end_with?('=')
          m = mid[0...-1].to_sym
          new_ostruct_member!(m)
          @table[m] = args.first
        elsif len.zero? && kwargs.blank? && !block
          Deprecation.warn(Blacklight::NestedOpenStructWithHashAccess,
                           "Initializing a #{nested_class} implicitly (by calling #{mid}) is deprecated. Call it as #{mid}! or pass initialize arguments")

          new_ostruct_member!(mid)
          @table[mid]
        else
          new_ostruct_member!(mid)
          @table[mid] = nested_class.new(key: mid, **(args.first || {}), **kwargs)
        end

  block&.call(res)

  res
end

Instance Attribute Details

#nested_classObject (readonly)

Returns the value of attribute nested_class.



11
12
13
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 11

def nested_class
  @nested_class
end

Instance Method Details

#<<(key) ⇒ Object

Add an new key to the object, with a default default



31
32
33
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 31

def << key
  @table[key]
end

#[]=(key, value) ⇒ Object

Add a new key/value to the object; if it’s a Hash, turn it into another NestedOpenStructWithHashAccess



38
39
40
41
42
43
44
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 38

def []=(key, value)
  if value.is_a? Hash
    send "#{key}=", nested_class.new({ key: key.to_sym }.merge(value))
  else
    super
  end
end

#deep_dupObject



65
66
67
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 65

def deep_dup
  self.class.new nested_class, @table.deep_dup
end

#marshal_dumpObject

Before serializing, we need to reset the default proc so it can be serialized appropriately



49
50
51
52
53
54
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 49

def marshal_dump
  h = to_h.dup
  h.default = nil

  [nested_class, h]
end

#marshal_load(x) ⇒ Object

After deserializing, we need to re-add the default proc to the internal hash



59
60
61
62
63
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 59

def marshal_load x
  @nested_class = x.first
  super x.last
  set_default_proc!
end

#merge(other_hash) ⇒ OpenStructWithHashAccess

Merge the values of this OpenStruct with another OpenStruct or Hash

Parameters:

  • other_hash (Hash, #to_h)

Returns:



77
78
79
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 77

def merge other_hash
  self.class.new nested_class, to_h.merge((other_hash if other_hash.is_a? Hash) || other_hash.to_h)
end

#merge!(other_hash) ⇒ OpenStructWithHashAccess

Merge the values of another OpenStruct or Hash into this object

Parameters:

  • other_hash (Hash, #to_h)

Returns:



85
86
87
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 85

def merge! other_hash
  @table.merge!(nested_class, (other_hash if other_hash.is_a? Hash) || other_hash.to_h)
end

#select(*args, &block) ⇒ Object



69
70
71
# File 'lib/blacklight/nested_open_struct_with_hash_access.rb', line 69

def select *args, &block
  self.class.new nested_class, to_h.select(*args, &block)
end