Class: Chutzen::Dictionary

Inherits:
Object
  • Object
show all
Defined in:
lib/chutzen/dictionary.rb

Overview

Holds a hash and allows retrieval of data with a simple lookup syntax.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = {}) ⇒ Dictionary

Creates a new Dictionary with an option initial hash of data.



7
8
9
10
# File 'lib/chutzen/dictionary.rb', line 7

def initialize(data = {})
  @data = data
  @mutex = Mutex.new
end

Class Method Details

.build(path, value) ⇒ Object



110
111
112
113
114
115
116
117
# File 'lib/chutzen/dictionary.rb', line 110

def self.build(path, value)
  reference, *rest = path
  if reference.is_a?(Numeric) && reference < 256
    build_array(reference, rest, value)
  else
    build_hash(reference, rest, value)
  end
end

.build_array(index, rest, value) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/chutzen/dictionary.rb', line 119

def self.build_array(index, rest, value)
  if rest.empty?
    [].insert(index, value)
  else
    [].insert(index, build(rest, value))
  end
end

.build_hash(key, rest, value) ⇒ Object



127
128
129
130
131
132
133
# File 'lib/chutzen/dictionary.rb', line 127

def self.build_hash(key, rest, value)
  if rest.empty?
    { key => value }
  else
    { key => build(rest, value) }
  end
end

.bury(data, path, value) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/chutzen/dictionary.rb', line 99

def self.bury(data, path, value)
  key, *rest = path
  if rest.empty?
    data[key] = value
  elsif data.key?(key)
    bury(data[key], rest, value)
  else
    data[key] = build(rest, value)
  end
end

.search(data, key) ⇒ Object

Searches the data depth-first for a key and returns the path to that key for the first match.



70
71
72
73
74
75
76
77
# File 'lib/chutzen/dictionary.rb', line 70

def self.search(data, key)
  case data
  when Hash
    search_hash(data, key)
  when Array
    search_array(data, key)
  end
end

.search_array(data, key) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/chutzen/dictionary.rb', line 91

def self.search_array(data, key)
  data.each.with_index do |item, index|
    path = search(item, key)
    return (path << index) if path
  end
  nil
end

.search_hash(data, key) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/chutzen/dictionary.rb', line 79

def self.search_hash(data, key)
  if data.key?(key)
    [key]
  else
    data.each do |name, value|
      path = search(value, key)
      return (path << name) if path
    end
    nil
  end
end

Instance Method Details

#[](key) ⇒ Object

Get a value using a dot expression (eg. ‘export.filename’). Does not work with deep search indentifiers.



18
19
20
# File 'lib/chutzen/dictionary.rb', line 18

def [](key)
  dig(*Chutzen::Expression.split(key))
end

#[]=(key, value) ⇒ Object



22
23
24
25
26
# File 'lib/chutzen/dictionary.rb', line 22

def []=(key, value)
  @mutex.synchronize do
    @data[key.to_s] = value
  end
end

#bury!(path, value) ⇒ Object

Add or replace a value with a path.



48
49
50
51
52
# File 'lib/chutzen/dictionary.rb', line 48

def bury!(path, value)
  @mutex.synchronize do
    self.class.bury(@data, path, value)
  end
end

#deep_merge!(data) ⇒ Object

Merge a hash into the dictionary without replacing existing values.



62
63
64
65
66
# File 'lib/chutzen/dictionary.rb', line 62

def deep_merge!(data)
  @mutex.synchronize do
    DeepMerge.new(@data, data).perform
  end
end

#dig(*path) ⇒ Object

See Hash#dig.



36
37
38
# File 'lib/chutzen/dictionary.rb', line 36

def dig(*path)
  @data.dig(*path)
end

#dig_deep(*path) ⇒ Object

Performs a depth first search for the first item in the path. After that it works just like dig on the rest of the path.



42
43
44
45
# File 'lib/chutzen/dictionary.rb', line 42

def dig_deep(*path)
  found_path = self.class.search(@data, path[0])
  found_path ? @data.dig(*(found_path.reverse + path[1..])) : nil
end

#exist?(*path) ⇒ Boolean

Returns true when a value was set for the path, so that means it also returns true when the value is nil.

Returns:

  • (Boolean)


30
31
32
33
# File 'lib/chutzen/dictionary.rb', line 30

def exist?(*path)
  data = path.length > 1 ? @data.dig(*path[0..-2]) : @data
  data&.key?(path.last)
end

#merge!(data) ⇒ Object

Merge a hash into the dictionary.



55
56
57
58
59
# File 'lib/chutzen/dictionary.rb', line 55

def merge!(data)
  @mutex.synchronize do
    @data.merge!(data)
  end
end

#to_hashObject



12
13
14
# File 'lib/chutzen/dictionary.rb', line 12

def to_hash
  @data
end