Module: Gorillib::Hashlike::DeepHash

Includes:
DeepCompact, DeepDup, DeepMerge
Defined in:
lib/gorillib/hashlike/deep_hash.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DeepDup

#deep_dup

Methods included from DeepCompact

#deep_compact!

Methods included from DeepMerge

#deep_merge, #deep_merge!

Class Method Details

.included(base) ⇒ Object



25
26
27
28
29
30
# File 'lib/gorillib/hashlike/deep_hash.rb', line 25

def self.included(base)
  base.class_eval do
    unless method_defined?(:regular_writer) then alias_method :regular_writer, :[]=  ; end
    unless method_defined?(:regular_update) then alias_method :regular_update, :update  ; end
  end
end

Instance Method Details

#[](attr) ⇒ Object

Gets a member value.

Given a deep key (one that contains '.'), uses it as a chain of hash memberships. Otherwise calls the normal hash member getter

Examples:

foo = DeepHash.new({ :hi => 'there', :howdy => { :doody => 3 } })
foo['howdy.doody'] # => 3
foo['hi']          # => 'there'
foo[:hi]           # => 'there'


60
61
62
63
# File 'lib/gorillib/hashlike/deep_hash.rb', line 60

def [] attr
  attr = convert_key(attr)
  attr.is_a?(Array) ? deep_get(*attr) : super(attr)
end

#[]=(attr, val) ⇒ Object

Sets a member value.

Given a deep key (one that contains '.'), uses it as a chain of hash memberships. Otherwise calls the normal hash member setter

Examples:

foo = DeepHash.new :hi => 'there'
foo['howdy.doody'] = 3
foo # => { :hi => 'there', :howdy => { :doody => 3 } }


42
43
44
45
46
# File 'lib/gorillib/hashlike/deep_hash.rb', line 42

def []= attr, val
  attr = convert_key(attr)
  val  = convert_value(val)
  attr.is_a?(Array) ? deep_set(*(attr | [val])) : super(attr, val)
end

#deep_delete(*args) ⇒ Object

Treat hash as tree of hashes:

x = { :a => :val, :subhash => { :a => :val1, :b => :val2 } }
x.deep_delete(:subhash, :a)
#=> :val
x
#=> { :a => :val, :subhash => { :b => :val2 } }


118
119
120
121
122
# File 'lib/gorillib/hashlike/deep_hash.rb', line 118

def deep_delete *args
  last_key  = args.pop                                   # key to delete
  last_hsh  = args.empty? ? self : (deep_get(*args)||{}) # hsh containing that key
  last_hsh.delete(last_key)
end

#deep_get(*args) ⇒ Object

Treat hash as tree of hashes:

x = { :a => :val_a, :subhash => { :b => :val_b } }
x.deep_get(:a)
# => :val_a
x.deep_get(:subhash, :c)
# => nil
x.deep_get(:subhash, :c, :f)
# => nil
x.deep_get(:subhash, :b)
# => nil


101
102
103
104
105
106
107
# File 'lib/gorillib/hashlike/deep_hash.rb', line 101

def deep_get *args
  last_key = args.pop
  # dig down to last subtree (building out if necessary)
  hsh = args.inject(self){|h, k| h[k] || self.class.new }
  # get leaf value
  hsh[last_key]
end

#deep_set(*args) ⇒ Object

Treat hash as tree of hashes:

x = { :a => :val, :subhash => { :b => :val_b } }
x.deep_set(:subhash, :cat, :hat)
# => { :a => :val, :subhash => { :b => :val_b,   :cat => :hat } }
x.deep_set(:subhash, :b, :newval)
# => { :a => :val, :subhash => { :b => :newval, :cat => :hat } }


75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/gorillib/hashlike/deep_hash.rb', line 75

def deep_set *args
  val      = args.pop
  last_key = args.pop
  # dig down to last subtree (building out if necessary)
  hsh = self
  args.each  do |key|
    hsh.regular_writer(key, self.class.new) unless hsh.has_key?(key)
    hsh = hsh[key]
  end
  # set leaf value
  hsh[last_key] = val
end

#initialize(constructor = {}) ⇒ Object

Parameters:

  • constructor (Object) (defaults to: {})

    The default value for the DeepHash. Defaults to an empty hash. If constructor is a Hash, adopt its values.



16
17
18
19
20
21
22
23
# File 'lib/gorillib/hashlike/deep_hash.rb', line 16

def initialize(constructor = {})
  if constructor.is_a?(Hash)
    super()
    deep_merge!(constructor) unless constructor.empty?
  else
    super(constructor)
  end
end