Class: Etcenv::VariableExpander
- Inherits:
-
Object
- Object
- Etcenv::VariableExpander
show all
- Defined in:
- lib/etcenv/variable_expander.rb
Defined Under Namespace
Classes: DepthLimitError, LoopError
Constant Summary
collapse
- MAX_DEPTH_DEFAULT =
50
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
Returns a new instance of VariableExpander.
14
15
16
|
# File 'lib/etcenv/variable_expander.rb', line 14
def initialize(variables)
@variables = variables.dup.freeze
end
|
Instance Attribute Details
#variables ⇒ Object
Returns the value of attribute variables.
18
19
20
|
# File 'lib/etcenv/variable_expander.rb', line 18
def variables
@variables
end
|
Class Method Details
.expand(variables, max = MAX_DEPTH_DEFAULT) ⇒ Object
10
11
12
|
# File 'lib/etcenv/variable_expander.rb', line 10
def self.expand(variables, max = MAX_DEPTH_DEFAULT)
new(variables).expand(max)
end
|
Instance Method Details
#dependees_by_variable ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
|
# File 'lib/etcenv/variable_expander.rb', line 34
def dependees_by_variable
@dependees_by_variable ||= variable_with_deps.inject({}) do |r, x|
k, v, deps = x[0], x[1][0], x[1][1]
deps.each do |dep|
r[dep] ||= []
r[dep] << k
end
r
end.freeze
end
|
#detect_loop! ⇒ Object
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# File 'lib/etcenv/variable_expander.rb', line 56
def detect_loop!
if !variables.empty? && root_variables.empty?
raise LoopError, "there's no possible root variables (variables which don't have dependee)"
else
dependees_by_variable.each do |k, deps|
deps.each do |dep|
if (dependees_by_variable[dep] || []).include?(k)
raise LoopError, "There's a loop between $#{dep} and $#{k}"
end
end
end
end
end
|
#expand(max = MAX_DEPTH_DEFAULT) ⇒ Object
20
21
22
23
24
25
26
27
28
|
# File 'lib/etcenv/variable_expander.rb', line 20
def expand(max = MAX_DEPTH_DEFAULT)
detect_loop!
result = {}
solve_order(max).map do |x|
result[x] = single_expand(@variables[x], result)
end
result
end
|
#root_variables ⇒ Object
46
47
48
49
50
51
52
53
54
|
# File 'lib/etcenv/variable_expander.rb', line 46
def root_variables
@root_variables ||= variable_with_deps.inject([]) do |r, x|
k, v, deps = x[0], x[1][0], x[1][1]
if deps.empty?
r << k
end
r
end + (variables.keys - dependees_by_variable.keys)
end
|
#solve_order(max_depth = 10) ⇒ Object
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/etcenv/variable_expander.rb', line 70
def solve_order(max_depth = 10)
order = []
solve = nil
solve = ->(vs, depth = 0) do
raise DepthLimitError if depth.succ > max_depth
vs.each do |x|
order.concat solve.call(dependees_by_variable[x] || [], depth.succ) + [x]
end
end
solve.call(root_variables)
Utils.uniq_with_keeping_first_appearance(order).reverse
end
|
#variable_with_deps ⇒ Object
30
31
32
|
# File 'lib/etcenv/variable_expander.rb', line 30
def variable_with_deps
@variables.map { |k, v| [k, [v, detect_variables(v)]] }
end
|