class Plaster::ModelDeconstructor

Deconstructs a hierarchical data structure comprised of struct-like and array-like objects into a homologous structure of hashes (HashWithIndifferentAccess) and arrays (Array).

Public Class Methods

default_instance() click to toggle source
# File lib/plaster/model_deconstructor.rb, line 14
def default_instance
  @default_instance ||= new
end

Public Instance Methods

bag_like?(obj) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 39
def bag_like?(obj)
  return true if \
    obj.respond_to?( :to_ary )

  return false if \
    obj.respond_to?( :to_hash )

  obj.respond_to?( :to_a   ) &&
  obj.respond_to?( :each   ) &&
  obj.respond_to?( :map    ) &&
  obj.respond_to?( :&      ) &&
  obj.respond_to?( :|      ) &&
  obj.respond_to?( :+      ) &&
  obj.respond_to?( :-      )
end
call(obj) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 23
def call(obj)
  if obj.respond_to?( :model_deconstruct )
    obj.model_deconstruct
  elsif obj.respond_to?( :to_hash )
    deconstruct_from_hash( obj )
  elsif bag_like?( obj )
    deconstruct_from_bag_like( obj )
  elsif hash_like?( obj )
    deconstruct_from_hash_like( obj )
  elsif map_like?( obj )
    deconstruct_from_map_like( obj )
  else
    obj
  end
end
deconstruct_from_bag_like(obj) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 71
def deconstruct_from_bag_like(obj)
  obj.map { |entry|
    call( entry )
  }
end
deconstruct_from_hash(hash) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 66
def deconstruct_from_hash(hash)
  hash = HashWIA.new( hash.to_hash )
  deconstruct_hash_values!( hash )
end
deconstruct_from_hash_like(obj) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 77
def deconstruct_from_hash_like(obj)
  hash = HashWithIndifferentAccess.new(obj.to_h)
  deconstruct_hash_values!( hash )
end
deconstruct_from_map_like(obj) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 82
def deconstruct_from_map_like(obj)
  hash = HashWIA.new.tap do |h|
    obj.each_pair do |k,v| ; h[k] = v ; end
  end
  deconstruct_hash_values!( hash )
end
deconstruct_hash_values!(hash) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 89
def deconstruct_hash_values!(hash)
  hash.each_pair do |k,v|
    dv = call( v )
    hash[k] = dv unless dv.equal?( v )
  end
  hash
end
hash_like?(obj) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 55
def hash_like?(obj)
  obj.respond_to?( :to_h      ) &&
  obj.respond_to?( :each_pair )
end
map_like?(obj) click to toggle source
# File lib/plaster/model_deconstructor.rb, line 60
def map_like?(obj)
  obj.respond_to?( :each_pair ) &&
  obj.respond_to?( :values    ) &&
  obj.respond_to?( :[]        )
end