Class: I18n::Tasks::Data::Tree::Siblings
Overview
Siblings represents a subtree sharing a common parent in case of an empty parent (nil) it represents a forest siblings’ keys are unique
Constant Summary
Constants included
from PluralKeys
PluralKeys::CLDR_CATEGORY_KEYS, PluralKeys::PLURAL_KEY_RE, PluralKeys::PLURAL_KEY_SUFFIXES
Instance Attribute Summary collapse
Attributes inherited from Nodes
#list
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from SplitKey
last_key_part, split_key
Methods included from PluralKeys
#collapse_plural_nodes!, #depluralize_key, #plural_forms?, #plural_nodes, #plural_suffix?
Methods inherited from Nodes
#children, #derive, #inspect, #to_hash, #to_nodes
Methods included from Traversal
#breadth_first, #depth_first, #get_nodes_by_key_filter, #grep_keys, #intersect_keys, #key_names, #key_values, #keys, #leaves, #levels, #nodes, #root_key_value_data, #root_key_values, #select_keys, #select_keys!, #select_nodes, #select_nodes!, #set_each_value!
Constructor Details
#initialize(opts = {}) ⇒ Siblings
Returns a new instance of Siblings.
17
18
19
20
21
22
23
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 17
def initialize(opts = {})
super(nodes: opts[:nodes])
@parent = opts[:parent] || first.try(:parent)
@list.map! { |node| node.parent == @parent ? node : node.derive(parent: @parent) }
@key_to_node = @list.each_with_object({}) { |node, h| h[node.key] = node }
@warn_about_add_children_to_leaf = opts.fetch(:warn_about_add_children_to_leaf, true)
end
|
Instance Attribute Details
#key_to_node ⇒ Object
Returns the value of attribute key_to_node.
15
16
17
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 15
def key_to_node
@key_to_node
end
|
#parent ⇒ Object
Returns the value of attribute parent.
15
16
17
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 15
def parent
@parent
end
|
Class Method Details
.build_forest(opts = {}) {|forest| ... } ⇒ Object
254
255
256
257
258
259
260
261
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 254
def build_forest(opts = {}, &block)
opts[:nodes] ||= []
parse_parent_opt!(opts)
forest = Siblings.new(opts)
yield(forest) if block
forest
end
|
.from_flat_pairs(pairs) ⇒ Object
build forest from [[Full Key, Value]]
311
312
313
314
315
316
317
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 311
def from_flat_pairs(pairs)
Siblings.new.tap do |siblings|
pairs.each do |full_key, value|
siblings[full_key] = ::I18n::Tasks::Data::Tree::Node.new(key: split_key(full_key).last, value: value)
end
end
end
|
.from_key_attr(key_attrs, opts = {}, &block) ⇒ Object
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 276
def from_key_attr(key_attrs, opts = {}, &block)
build_forest(opts) do |forest|
key_attrs.each do |(full_key, attr)|
fail "Invalid key #{full_key.inspect}" if full_key.end_with?('.')
node = ::I18n::Tasks::Data::Tree::Node.new(**attr.merge(key: split_key(full_key).last))
yield(full_key, node) if block
forest[full_key] = node
end
end
end
|
.from_key_names(keys, opts = {}, &block) ⇒ Object
288
289
290
291
292
293
294
295
296
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 288
def from_key_names(keys, opts = {}, &block)
build_forest(opts) do |forest|
keys.each do |full_key|
node = ::I18n::Tasks::Data::Tree::Node.new(key: split_key(full_key).last)
yield(full_key, node) if block
forest[full_key] = node
end
end
end
|
.from_key_occurrences(key_occurrences) ⇒ Siblings
265
266
267
268
269
270
271
272
273
274
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 265
def from_key_occurrences(key_occurrences)
build_forest(warn_about_add_children_to_leaf: false) do |forest|
key_occurrences.each do |key_occurrence|
forest[key_occurrence.key] = ::I18n::Tasks::Data::Tree::Node.new(
key: split_key(key_occurrence.key).last,
data: { occurrences: key_occurrence.occurrences }
)
end
end
end
|
.from_nested_hash(hash, opts = {}) ⇒ Object
Also known as:
[]
build forest from nested hash, e.g. {‘es’ => { ‘common’ => { name => ‘Nombre’, ‘age’ => ‘Edad’ } } } this is the native i18n gem format
300
301
302
303
304
305
306
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 300
def from_nested_hash(hash, opts = {})
parse_parent_opt!(opts)
fail I18n::Tasks::CommandError, "invalid tree #{hash.inspect}" unless hash.respond_to?(:map)
opts[:nodes] = hash.map { |key, value| Node.from_key_value key, value }
Siblings.new(opts)
end
|
.null ⇒ Object
250
251
252
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 250
def null
new
end
|
Instance Method Details
#append(nodes) ⇒ Object
142
143
144
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 142
def append(nodes)
derive.append!(nodes)
end
|
#append!(nodes) ⇒ Object
132
133
134
135
136
137
138
139
140
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 132
def append!(nodes)
nodes = nodes.map do |node|
fail "already has a child with key '#{node.key}'" if key_to_node.key?(node.key)
key_to_node[node.key] = (node.parent == parent ? node : node.derive(parent: parent))
end
super(nodes)
self
end
|
#attributes ⇒ Object
25
26
27
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 25
def attributes
super.merge(parent: @parent)
end
|
#get(full_key) ⇒ Node
Also known as:
[]
83
84
85
86
87
88
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 83
def get(full_key)
first_key, rest = split_key(full_key.to_s, 2)
node = key_to_node[first_key]
node = node.children.try(:get, rest) if rest && node
node
end
|
#merge(nodes) ⇒ Object
155
156
157
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 155
def merge(nodes)
derive.merge!(nodes)
end
|
#merge!(nodes, on_leaves_merge: nil) ⇒ Object
147
148
149
150
151
152
153
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 147
def merge!(nodes, on_leaves_merge: nil)
nodes = Siblings.from_nested_hash(nodes) if nodes.is_a?(Hash)
nodes.each do |node|
merge_node! node, on_leaves_merge: on_leaves_merge
end
self
end
|
#merge_node!(node, on_leaves_merge: nil) ⇒ Object
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 184
def merge_node!(node, on_leaves_merge: nil) if key_to_node.key?(node.key)
our = key_to_node[node.key]
return if our == node
our.value = node.value if node.leaf?
our.data.merge!(node.data) if node.data?
if node.children?
if our.children
our.children.merge!(node.children)
else
conditionally_warn_add_children_to_leaf(our, node.children)
our.children = node.children
end
elsif on_leaves_merge
on_leaves_merge.call(our, node)
end
else
@list << (key_to_node[node.key] = node.derive(parent: parent))
dirty!
end
end
|
#mv_key!(from_pattern, to_pattern, root: false, retain: false) ⇒ old key => new key
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 39
def mv_key!(from_pattern, to_pattern, root: false, retain: false) moved_forest = Siblings.new
moved_nodes = []
old_key_to_new_key = {}
nodes do |node|
full_key = node.full_key(root: root)
if from_pattern =~ full_key
moved_nodes << node
if to_pattern.empty?
old_key_to_new_key[full_key] = nil
next
end
match = $~
new_key = to_pattern.gsub(/\\\d+/) { |m| match[m[1..].to_i] }
old_key_to_new_key[full_key] = new_key
moved_forest.merge!(Siblings.new.tap do |forest|
forest[[(node.root.try(:key) unless root), new_key].compact.join('.')] =
node.derive(key: split_key(new_key).last)
end)
end
end
nodes do |node|
next unless node.reference?
old_target = [(node.root.key if root), node.value.to_s].compact.join('.')
new_target = old_key_to_new_key[old_target]
if new_target
new_target = new_target.sub(/\A[^.]*\./, '') if root
node.value = new_target.to_sym
end
end
remove_nodes_and_emptied_ancestors!(moved_nodes) unless retain
merge! moved_forest
old_key_to_new_key
end
|
#remove!(node) ⇒ Object
methods below change state
126
127
128
129
130
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 126
def remove!(node)
super
key_to_node.delete(node.key)
self
end
|
#remove_nodes_and_emptied_ancestors(nodes) ⇒ Object
208
209
210
211
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 208
def remove_nodes_and_emptied_ancestors(nodes)
add_ancestors_that_only_contain_nodes! nodes
select_nodes { |node| !nodes.include?(node) }
end
|
#remove_nodes_and_emptied_ancestors!(nodes) ⇒ Object
214
215
216
217
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 214
def remove_nodes_and_emptied_ancestors!(nodes)
add_ancestors_that_only_contain_nodes! nodes
select_nodes! { |node| !nodes.include?(node) }
end
|
#rename_key(key, new_key) ⇒ Object
29
30
31
32
33
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 29
def rename_key(key, new_key)
node = key_to_node.delete(key)
replace_node! node, node.derive(key: new_key)
self
end
|
#replace_node!(node, new_node) ⇒ Object
77
78
79
80
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 77
def replace_node!(node, new_node)
@list[@list.index(node)] = new_node
key_to_node[new_node.key] = new_node
end
|
#set(full_key, node) ⇒ Object
Also known as:
[]=
add or replace node by full key
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 93
def set(full_key, node)
fail 'value should be a I18n::Tasks::Data::Tree::Node' unless node.is_a?(Node)
key_part, rest = split_key(full_key, 2)
child = key_to_node[key_part]
if rest
unless child
child = Node.new(
key: key_part,
parent: parent,
children: [],
warn_about_add_children_to_leaf: @warn_about_add_children_to_leaf
)
append! child
end
unless child.children
conditionally_warn_add_children_to_leaf(child, [])
child.children = []
end
child.children.set rest, node
else
remove! child if child
append! node
end
dirty!
node
end
|
#set_root_key!(new_key, data = nil) ⇒ Object
175
176
177
178
179
180
181
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 175
def set_root_key!(new_key, data = nil)
return self if empty?
rename_key first.key, new_key
leaves { |node| node.data.merge! data } if data
self
end
|
#subtract_by_key(other) ⇒ Object
167
168
169
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 167
def subtract_by_key(other)
subtract_keys other.key_names(root: true)
end
|
#subtract_by_key!(other) ⇒ Object
171
172
173
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 171
def subtract_by_key!(other)
subtract_keys! other.key_names(root: true)
end
|
#subtract_keys(keys) ⇒ Object
159
160
161
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 159
def subtract_keys(keys)
remove_nodes_and_emptied_ancestors(find_nodes(keys))
end
|
#subtract_keys!(keys) ⇒ Object
163
164
165
|
# File 'lib/i18n/tasks/data/tree/siblings.rb', line 163
def subtract_keys!(keys)
remove_nodes_and_emptied_ancestors!(find_nodes(keys))
end
|