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_transform_keys(&:to_sym)
  @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
50
51
52
53
54
# File 'lib/key_tree/tree.rb', line 47

def [](key_path)
  fetch(key_path) do
    next default_proc.call(self, key_path) unless default_proc.nil?
    default
  end
rescue KeyError
  default
end

#delete(key_path) ⇒ Object



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

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

#delete!(key_path) ⇒ Object



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

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

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



56
57
58
# File 'lib/key_tree/tree.rb', line 56

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

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

Returns:

  • (Boolean)


98
99
100
101
102
103
# File 'lib/key_tree/tree.rb', line 98

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


91
92
93
94
95
# File 'lib/key_tree/tree.rb', line 91

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


140
141
142
# File 'lib/key_tree/tree.rb', line 140

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


129
130
131
132
# File 'lib/key_tree/tree.rb', line 129

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

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

Returns:

  • (Boolean)


109
110
111
112
113
114
115
116
# File 'lib/key_tree/tree.rb', line 109

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



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

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: []=



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

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)


119
120
121
# File 'lib/key_tree/tree.rb', line 119

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

#values_at(*key_paths) ⇒ Object



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

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