Class | ArkanisDevelopment::SimpleLocalization::NestedHash |
In: |
lib/nested_hash.rb
|
Parent: | Hash |
A NestedHash is an extended Hash to make handling of nested hash structures easier. It adds a quick way to access and set keys of nested hashes as well as recursive merge! and dup methods to merge or duplicate structures.
nh = NestedHash.from {:a => 1, :b => {:x => 9}} nh = NestedHash[:a => 1, :b => {:x => 9}] nh[:a] # => 1 nh[:b, :x] # => 9 nh[:b, :y] = 88 nh # => {:a => 1, :b => {:x => 9, :y => 88}} nh.merge! {:c => 2, :b => {:z => 'end'} nh # => {:a => 1, :b => {:x => 9, :y => 88, :z => 'end'}, :c => 2}
Creates a new NestedHash object out of an ordinary hash (or anything that is based on the class Hash).
# File lib/nested_hash.rb, line 23 23: def self.from(hash) 24: return nil unless hash.kind_of?(Hash) 25: return hash if hash.kind_of?(self) 26: new_nested_hash = self.new 27: hash.each do |key, value| 28: new_nested_hash[key] = value 29: end 30: new_nested_hash 31: end
Gets a key out of the hash. To make access to keys of nested hashes easier you can specify multiple keys, one per level.
h = NestedHash[:a => 1, :b => {:x => 10, :y => 'test'}] h[:a] # => 1 h[:b, :x] # => 10 h[:b, :y] # => 'test' h[:b, :dummy] #=> nil
Please note that ordinary hashes inside the hierarchical hash are not altered. If you access them they will be returned as ordinary hashes.
# File lib/nested_hash.rb, line 44 44: def [](*keys) 45: if keys.length <= 1 46: super 47: else 48: keys.inject(self) do |memo, key| 49: memo[key] if memo and memo.kind_of?(Hash) 50: end || (self.default_proc ? self.default_proc.call : nil) || self.default 51: end 52: end
Sets a key to the specified value. To make access to keys of nested hashes easier you can specify multiple keys, one per level. If the specified series of keys (the nested hashes inside) does not exist the necessary hashes inside this NestedHash will be created automatically.
h = HierarchicalHash[:a => 1, :b => {:x => 10, :y => 'test'}] h[:a] = 2 h[:b, :x] = 20 h[:b, :y] = 'next test' h[:dummy, :next] # => nil h[:dummy, :next] = 'auto create of nested hashes' h[:dummy, :next] # => 'auto create of nested hashes'
# File lib/nested_hash.rb, line 68 68: def []=(*args) 69: if args.length <= 2 70: super 71: else 72: value = args.pop 73: last_key = args.pop 74: keys = args 75: 76: target_hash = keys.inject(self) do |memo, key| 77: begin memo[key] rescue nil end || memo[key] = {} 78: end 79: 80: target_hash[last_key] = value 81: value 82: end 83: end
Duplicates this NeastedHash and (recursive) all hashes within it.
Please note that all hashes within this NeastedHash are converted to NeastedHash objects.
# File lib/nested_hash.rb, line 104 104: def dup 105: new_dup = super 106: new_dup.each do |key, value| 107: new_dup[key] = self.class.from(value).dup if value.kind_of?(Hash) 108: end 109: end
Merges the hash other_hash into this nested hash.
Please note that this method modifies this nested hash directly and does not work on a copy. Hash inside these two objects are converted to NestedHash objects during the merge process.
Based on "Hash recursive merge in Ruby" by Rex Chung: www.rexchung.com/2007/02/01/hash-recursive-merge-in-ruby/ Added a bit more spice and flexibility…
# File lib/nested_hash.rb, line 94 94: def merge!(other_hash) 95: super(other_hash) do |key, old_val, new_val| 96: if old_val.kind_of?(Hash) then self.class.from(old_val).merge!(new_val) else new_val end 97: end 98: end