module NeoHash::Support

Provides attribute readers and Hash features A class that includes this has `@h` as inner hash. @example

class DynamicObject
  include NeoHash::Support

  def initialize(hash)
    set_inner_hash(hash)
  end
end

obj = DynamicObject.new({ port: 80, "host" => "localhost" })
p obj.port   # 80
p obj[:host] # "localhost"
obj[:host] = "192.168.1.1"
p obj.host   # "192.168.1.1"

Public Instance Methods

[](key) click to toggle source

@see Hash#[]

# File lib/neo_hash/support.rb, line 20
def [](key)
  @h[key.to_sym]
end
[]=(key, value) click to toggle source

@see Hash#[]=

# File lib/neo_hash/support.rb, line 25
def []=(key, value)
  sk = key.to_sym
  define_attr_accessor(sk) unless @h.key?(sk)
  @h[sk] = convert_val(value)
end
delete(key, &block) click to toggle source

@see Hash#delete

# File lib/neo_hash/support.rb, line 41
def delete(key, &block)
  @h.delete(key.to_sym, &block)
end
fetch(*args, &block) click to toggle source

@see Hash#fetch

# File lib/neo_hash/support.rb, line 46
def fetch(*args, &block)
  args[0] = args[0].to_sym
  @h.fetch(*args, &block)
end
has_key?(key)
Alias for: include?
include?(key) click to toggle source

@see Hash#include?

# File lib/neo_hash/support.rb, line 32
def include?(key)
  @h.include?(key.to_sym)
end
Also aliased as: has_key?, key?, member?
key?(key)
Alias for: include?
member?(key)
Alias for: include?
method_missing(method, *args, &block) click to toggle source
Calls superclass method
# File lib/neo_hash/support.rb, line 51
def method_missing(method, *args, &block)
  if Hash.public_method_defined?(method)
    @h.send method, *args, &block
  else
    super
  end
end
to_h(opts = {}) click to toggle source

Convert to original Hash

@return [Hash] hash @param [Hash] opts the options to intialize @option opts [String] :symbolize_keys (true) whether symbolize names or not

# File lib/neo_hash/support.rb, line 64
def to_h(opts = {})
  symbolize = opts.fetch(:symbolize_keys, true)

  @h.map {|key, val|
    [symbolize ? key : key.to_s, to_primitive(val, opts)]
  }.to_h
end
to_hash() click to toggle source

Implicitly convert to Hash @return [Hash] generated hash

# File lib/neo_hash/support.rb, line 74
def to_hash
  to_h
end

Protected Instance Methods

set_inner_hash(hash) click to toggle source

Set inner hash and replace hashes in descendant with wrapping them recursively

# File lib/neo_hash/support.rb, line 81
def set_inner_hash(hash)
  @h = coerce_hash(hash)
  define_attr_accessors
end

Private Instance Methods

coerce_hash(hash) click to toggle source
# File lib/neo_hash/support.rb, line 97
def coerce_hash(hash)
  {}.tap do |new_h|
    hash.each do |name, val|
      new_h[name.to_sym] = convert_val(val)
    end
  end
end
convert_val(val) click to toggle source
# File lib/neo_hash/support.rb, line 105
def convert_val(val)
  return NeoHash.new(val) if val.is_a?(Hash)
  return val.map {|item| convert_val(item) } if val.instance_of?(Array)
  val
end
define_attr_accessor(name) click to toggle source
# File lib/neo_hash/support.rb, line 92
def define_attr_accessor(name)
  define_singleton_method name, lambda { @h[name] }
  define_singleton_method "#{name}=", lambda {|val| @h[name] = convert_val(val) }
end
define_attr_accessors() click to toggle source
# File lib/neo_hash/support.rb, line 88
def define_attr_accessors
  @h.each_key {|name| define_attr_accessor(name) }
end
to_primitive(val, opts) click to toggle source
# File lib/neo_hash/support.rb, line 111
def to_primitive(val, opts)
  return val.to_h(opts) if val.instance_of?(NeoHash)
  return val.to_hash if val.respond_to?(:to_hash)
  return val.map {|item| to_primitive(item, opts) } if val.instance_of?(Array)
  val
end