class ConfigHound::Interpolation::Context

Interpolation context

Attributes

root[R]
seen[R]

Public Class Methods

new(root, seen = Set.new) click to toggle source
# File lib/config_hound/interpolation.rb, line 21
def initialize(root, seen = Set.new)
  @root = root
  @seen = seen.freeze
end

Public Instance Methods

expand(input) click to toggle source
# File lib/config_hound/interpolation.rb, line 29
def expand(input)
  case input
  when Hash
    expand_hash(input)
  when Array
    expand_array(input)
  when /\A<\(([\w.]+)\)>\Z/
    evaluate_expression($1)
  when /<\([\w.]+\)>/
    input.gsub(/<\(([\w.]+)\)>/) do
      evaluate_expression($1)
    end
  else
    input
  end
end

Private Instance Methods

evaluate_expression(expr) click to toggle source
# File lib/config_hound/interpolation.rb, line 65
def evaluate_expression(expr)
  if seen.include?(expr)
    details = seen.map { |e| "<(#{e})>" }.join(", ")
    raise CircularReferenceError, "circular reference: #{details}"
  end
  words = expr.split(".")
  expansion = root.dig(*words)
  if expansion.nil?
    raise ReferenceError, "cannot resolve reference: <(#{expr})>"
  end
  subcontext = Context.new(root, seen + [expr])
  subcontext.expand(expansion)
end
expand_array(input) click to toggle source
# File lib/config_hound/interpolation.rb, line 54
def expand_array(input)
  input.each_with_object([]) do |v, result|
    case v
    when /\A<\*\(([\w.]+)\)>\Z/
      result.push(*evaluate_expression($1))
    else
      result.push(expand(v))
    end
  end
end
expand_hash(input) click to toggle source
# File lib/config_hound/interpolation.rb, line 48
def expand_hash(input)
  input.each_with_object({}) do |(k,v), a|
    a[k] = expand(v)
  end
end