Class: KeyTree::Tree

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
MetaData
Defined in:
lib/key_tree/tree.rb

Overview

A tree of key-value lookup tables (hashes)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MetaData

#meta_data, #with_meta_data

Constructor Details

#initialize(hash = {}, default = nil, &default_proc) ⇒ Tree

Returns a new instance of Tree.



26
27
28
29
30
# File 'lib/key_tree/tree.rb', line 26

def initialize(hash = {}, default = nil, &default_proc)
  @hash = hash.to_h.deep_key_pathify
  @default = default
  @default_proc = default_proc
end

Instance Attribute Details

#defaultObject (readonly)

Returns the value of attribute default.



32
33
34
# File 'lib/key_tree/tree.rb', line 32

def default
  @default
end

#default_procObject (readonly)

Returns the value of attribute default_proc.



32
33
34
# File 'lib/key_tree/tree.rb', line 32

def default_proc
  @default_proc
end

Class Method Details

.[](hash = {}) ⇒ Object

KeyTree::Tree.new(hash)

Initialize a new KeyTree from nested Hash:es



22
23
24
# File 'lib/key_tree/tree.rb', line 22

def self.[](hash = {})
  new(hash)
end

Instance Method Details

#[](key_path) ⇒ Object



47
48
49
# File 'lib/key_tree/tree.rb', line 47

def [](key_path)
  fetch_default(key_path, default)
end

#delete(key_path) ⇒ Object



77
78
79
# File 'lib/key_tree/tree.rb', line 77

def delete(key_path)
  @hash.deep_delete(key_path.to_key_path)
end

#delete!(key_path) ⇒ Object



81
82
83
84
85
86
# File 'lib/key_tree/tree.rb', line 81

def delete!(key_path)
  delete(key_path)
rescue KeyError
  key_path = key_path[0..-2]
  retry
end

#fetch(key_path, *args, &key_missing) ⇒ Object



61
62
63
# File 'lib/key_tree/tree.rb', line 61

def fetch(key_path, *args, &key_missing)
  @hash.deep_fetch(key_path.to_key_path, *args, &key_missing)
end

#fetch_default(key_path, *default) ⇒ Object

Raises:

  • (KeyError)


51
52
53
54
55
56
57
58
59
# File 'lib/key_tree/tree.rb', line 51

def fetch_default(key_path, *default)
  catch do |ball|
    return fetch(key_path) { throw ball }
  end
  return default_proc.call(self, key_path) unless default_proc.nil?
  return yield(key_path) if block_given?
  return default.first unless default.empty?
  raise KeyError, %(key not found: "#{key_path}")
end

#include?(key_path) ⇒ Boolean Also known as: key?, has_key?, key_path?, has_key_path?

Returns:

  • (Boolean)


103
104
105
106
107
108
# File 'lib/key_tree/tree.rb', line 103

def include?(key_path)
  fetch(key_path)
  true
rescue KeyError
  false
end

#keysObject Also known as: key_paths

Return all maximal key paths in a tree

:call-seq:

keys => Array of KeyTree::Path


96
97
98
99
100
# File 'lib/key_tree/tree.rb', line 96

def keys
  @hash.deep.each_with_object([]) do |(key_path, value), result|
    result << key_path.to_key_path unless value.is_a?(Hash)
  end
end

#merge(other, &block) ⇒ Object Also known as: +

Return a new tree by merging values from other tree

:call-seq:

merge(other) => Tree
merge(other) { |key, lhs, rhs| } => Tree


145
146
147
# File 'lib/key_tree/tree.rb', line 145

def merge(other, &block)
  @hash.deep_merge(other.to_h, &block).to_key_tree
end

#merge!(other, &block) ⇒ Object Also known as: <<

Merge values from other tree into self

:call-seq:

merge!(other) => self
merge!(other) { |key, lhs, rhs| } => self


134
135
136
137
# File 'lib/key_tree/tree.rb', line 134

def merge!(other, &block)
  @hash.deep_merge!(other.to_h, &block)
  self
end

#prefix?(key_path) ⇒ Boolean Also known as: has_prefix?

Returns:

  • (Boolean)


114
115
116
117
118
119
120
121
# File 'lib/key_tree/tree.rb', line 114

def prefix?(key_path)
  key_path.to_key_path.reduce(@hash) do |subtree, key|
    return false unless subtree.is_a?(Hash)
    return false unless subtree.key?(key)
    subtree[key]
  end
  true
end

#store(key_path, new_value) ⇒ Object



65
66
67
# File 'lib/key_tree/tree.rb', line 65

def store(key_path, new_value)
  @hash.deep_store(key_path.to_key_path, new_value)
end

#store!(key_path, new_value) ⇒ Object Also known as: []=



69
70
71
72
73
74
# File 'lib/key_tree/tree.rb', line 69

def store!(key_path, new_value)
  store(key_path, new_value)
rescue KeyError
  delete!(key_path)
  retry
end

#to_yamlObject

Convert a Tree to YAML, with string keys

:call-seq:

to_yaml => String


43
44
45
# File 'lib/key_tree/tree.rb', line 43

def to_yaml
  to_h.deep_transform_keys(&:to_s).to_yaml
end

#value?(needle) ⇒ Boolean Also known as: has_value?

Returns:

  • (Boolean)


124
125
126
# File 'lib/key_tree/tree.rb', line 124

def value?(needle)
  @hash.deep.lazy.any? { |(_, straw)| straw == needle }
end

#values_at(*key_paths) ⇒ Object



88
89
90
# File 'lib/key_tree/tree.rb', line 88

def values_at(*key_paths)
  key_paths.map { |key_path| self[key_path] }
end