class Blacklight::NestedOpenStructWithHashAccess

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

Attributes

nested_class[R]

Public Class Methods

new(klass, hash = {}) click to toggle source
Calls superclass method
# 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

Public Instance Methods

<<(key) click to toggle source

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

# File lib/blacklight/nested_open_struct_with_hash_access.rb, line 31
def << key
  @table[key]
end
[]=(key, value) click to toggle source

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

Calls superclass method
# 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_dup() click to toggle source
# 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_dump() click to toggle source

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

# 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) click to toggle source

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

Calls superclass method
# 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) click to toggle source

Merge the values of this OpenStruct with another OpenStruct or Hash @param [Hash,#to_h] other_hash @return [OpenStructWithHashAccess] a new instance of an OpenStructWithHashAccess

# 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) click to toggle source

Merge the values of another OpenStruct or Hash into this object @param [Hash,#to_h] other_hash @return [OpenStructWithHashAccess] a new instance of an OpenStructWithHashAccess

# 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
method_missing(mid, *args, **kwargs, &block) click to toggle source

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

# 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
select(*args, &block) click to toggle source
# 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

Private Instance Methods

set_default_proc!() click to toggle source
# File lib/blacklight/nested_open_struct_with_hash_access.rb, line 121
def set_default_proc!
  self.default_proc = lambda do |hash, key|
    hash[key] = nested_class.new(key: key)
  end
end