class Hashr

Constants

TEMPLATE
VERSION

Attributes

raise_missing_keys[RW]

Public Class Methods

deep_accessorize(hash) click to toggle source
# File lib/hashr.rb, line 27
def deep_accessorize(hash)
  hash.each do |key, value|
    next unless value.is_a?(Hash)
    value[:_access] ||= []
    value[:_access] = Array(value[:_access])
    value.keys.each { |key| value[:_access] << key if value.respond_to?(key) }
    deep_accessorize(value)
  end
end
default(defaults) click to toggle source
# File lib/hashr.rb, line 19
def default(defaults)
  @defaults = deep_accessorize(defaults)
end
defaults() click to toggle source
# File lib/hashr.rb, line 23
def defaults
  @defaults ||= {}
end
define(definition) click to toggle source
# File lib/hashr.rb, line 11
def define(definition)
  @definition = deep_accessorize(definition.deep_symbolize_keys)
end
definition() click to toggle source
# File lib/hashr.rb, line 15
def definition
  @definition ||= {}
end
new(data = {}, definition = self.class.definition, &block) click to toggle source
# File lib/hashr.rb, line 40
def initialize(data = {}, definition = self.class.definition, &block)
  replace((deep_hashrize(definition.deep_merge((data || {}).deep_symbolize_keys))))
  deep_defaultize(self)
  (class << self; self; end).class_eval(&block) if block_given?
end

Public Instance Methods

[](key, default = nil) click to toggle source
Calls superclass method
# File lib/hashr.rb, line 46
def [](key, default = nil)
  store(key.to_sym, Hashr.new(default)) if default && !key?(key)
  super(key.to_sym)
end
[]=(key, value) click to toggle source
Calls superclass method
# File lib/hashr.rb, line 51
def []=(key, value)
  super(key.to_sym, value.is_a?(Hash) ? self.class.new(value, {}) : value)
end
include_accessors(accessors) click to toggle source
# File lib/hashr.rb, line 80
def include_accessors(accessors)
  Array(accessors).each { |accessor| meta_class.send(:define_method, accessor) { self[accessor] } } if accessors
end
include_modules(modules) click to toggle source
# File lib/hashr.rb, line 76
def include_modules(modules)
  Array(modules).each { |mod| meta_class.send(:include, mod) } if modules
end
meta_class() click to toggle source
# File lib/hashr.rb, line 84
def meta_class
  class << self; self end
end
method_missing(name, *args, &block) click to toggle source
# File lib/hashr.rb, line 64
def method_missing(name, *args, &block)
  case name.to_s[-1, 1]
  when '?'
    !!self[name.to_s[0..-2].to_sym]
  when '='
    self[name.to_s[0..-2].to_sym] = args.first
  else
    raise(IndexError.new("Key #{name.inspect} is not defined.")) if !key?(name) && self.class.raise_missing_keys
    self[name]
  end
end
respond_to?(*args) click to toggle source
# File lib/hashr.rb, line 60
def respond_to?(*args)
  true
end
set(path, value, stack = []) click to toggle source
# File lib/hashr.rb, line 55
def set(path, value, stack = [])
  tokens = path.to_s.split('.')
  tokens.size == 1 ? self[path] = value : self[tokens.shift, Hashr.new].set(tokens.join('.'), value, stack)
end
to_hash() click to toggle source
# File lib/hashr.rb, line 88
def to_hash
  inject({}) do |hash, (key, value)|
    hash[key] = value.is_a?(Hashr) ? value.to_hash : value
    hash
  end
end

Protected Instance Methods

deep_defaultize(hash) click to toggle source
# File lib/hashr.rb, line 111
def deep_defaultize(hash)
  self.class.defaults.each do |key, value|
    case key.to_sym
    when :_include
      hash.include_modules(value)
    when :_access
      hash.include_accessors(value)
    end
  end

  hash.each do |key, value|
    deep_defaultize(value) if value.is_a?(Hash)
  end

  hash
end
deep_hashrize(hash) click to toggle source
# File lib/hashr.rb, line 97
def deep_hashrize(hash)
  hash.inject(TEMPLATE.dup) do |result, (key, value)|
    case key.to_sym
    when :_include
      result.include_modules(value)
    when :_access
      result.include_accessors(value)
    else
      result.store(key.to_sym, value.is_a?(Hash) ? deep_hashrize(value) : value)
    end
    result
  end
end