class Puppet::Context

Puppet::Context is a system for tracking services and contextual information that puppet needs to be able to run. Values are “bound” in a context when it is created and cannot be changed; however a child context can be created, using {override}, that provides a different value.

When binding a {Proc}, the proc is called when the value is looked up, and the result is memoized for subsequent lookups. This provides a lazy mechanism that can be used to delay expensive production of values until they are needed.

@api private

Public Instance Methods

lookup(name, &block) click to toggle source

@api private

# File lib/puppet/context.rb, line 47
def lookup(name, &block)
  if @table.include?(name)
    value = @table[name]
    value.is_a?(Proc) ? (@table[name] = value.call) : value
  elsif block
    block.call
  else
    raise UndefinedBindingError, "no '#{name}' in #{@table.inspect} at top of #{@stack.inspect}"
  end
end
mark(name) click to toggle source

Mark a place on the context stack to later return to with {rollback}.

@param name [Object] The identifier for the mark

@api private

# File lib/puppet/context.rb, line 74
def mark(name)
  if @rollbacks[name].nil?
    @rollbacks[name] = @stack[-1][0]
  else
    raise DuplicateRollbackMarkError, "Mark for '#{name}' already exists"
  end
end
override(bindings, description = "") { || ... } click to toggle source

@api private

# File lib/puppet/context.rb, line 59
def override(bindings, description = "", &block)
  mark_point = "override over #{@stack[-1][0]}"
  mark(mark_point)
  push(bindings, description)

  yield
ensure
  rollback(mark_point)
end
pop() click to toggle source

@api private

# File lib/puppet/context.rb, line 38
def pop
  if @stack[-1][0] == 0
    raise(StackUnderflow, "Attempted to pop, but already at root of the context stack.")
  else
    (_, @table, @description) = @stack.pop
  end
end
push(overrides, description = "") click to toggle source

@api private

# File lib/puppet/context.rb, line 30
def push(overrides, description = "")
  @id += 1
  @stack.push([@id, @table, @description])
  @table = @table.merge(overrides || {})
  @description = description
end
rollback(name) click to toggle source

Roll back to a mark set by {mark}.

Rollbacks can only reach a mark accessible via {pop}. If the mark is not on the current context stack the behavior of rollback is undefined.

@param name [Object] The identifier for the mark

@api private

# File lib/puppet/context.rb, line 90
def rollback(name)
  if @rollbacks[name].nil?
    raise UnknownRollbackMarkError, "Unknown mark '#{name}'"
  end

  while @stack[-1][0] != @rollbacks[name]
    pop
  end

  @rollbacks.delete(name)
end

Public Class Methods

new(initial_bindings) click to toggle source

@api private

# File lib/puppet/context.rb, line 21
def initialize(initial_bindings)
  @table = initial_bindings
  @description = "root"
  @id = 0
  @rollbacks = {}
  @stack = [[0, nil, nil]]
end