class Puppet::Pops::Loader::BaseLoader

BaseLoader

An abstract implementation of Loader

A derived class should implement `find(typed_name)` and set entries, and possible handle “miss caching”.

@api private

Attributes

parent[R]

The parent loader

Public Class Methods

new(parent_loader, loader_name, environment) click to toggle source
Calls superclass method
   # File lib/puppet/pops/loader/base_loader.rb
16 def initialize(parent_loader, loader_name, environment)
17   super(loader_name, environment)
18   @parent = parent_loader # the higher priority loader to consult
19   @named_values = {}      # hash name => NamedEntry
20   @last_result = nil      # the value of the last name (optimization)
21 end

Public Instance Methods

add_entry(type, name, value, origin) click to toggle source

@api private

    # File lib/puppet/pops/loader/base_loader.rb
 98 def add_entry(type, name, value, origin)
 99   set_entry(TypedName.new(type, name), value, origin)
100 end
discover(type, error_collector = nil, name_authority = Pcore::RUNTIME_NAME_AUTHORITY) { |key| ... } click to toggle source
   # File lib/puppet/pops/loader/base_loader.rb
23 def discover(type, error_collector = nil, name_authority = Pcore::RUNTIME_NAME_AUTHORITY, &block)
24   result = []
25   @named_values.each_pair do |key, entry|
26     result << key unless entry.nil? || entry.value.nil? || key.type != type || (block_given? && !yield(key))
27   end
28   result.concat(parent.discover(type, error_collector, name_authority, &block))
29   result.uniq!
30   result
31 end
get_entry(typed_name) click to toggle source

This method is final (subclasses should not override it)

@api private

   # File lib/puppet/pops/loader/base_loader.rb
68 def get_entry(typed_name)
69   @named_values[typed_name]
70 end
load_typed(typed_name) click to toggle source

@api public

   # File lib/puppet/pops/loader/base_loader.rb
35 def load_typed(typed_name)
36   # The check for "last queried name" is an optimization when a module searches. First it checks up its parent
37   # chain, then itself, and then delegates to modules it depends on.
38   # These modules are typically parented by the same
39   # loader as the one initiating the search. It is inefficient to again try to search the same loader for
40   # the same name.
41   synchronize do
42     if @last_result.nil? || typed_name != @last_result.typed_name
43       @last_result = internal_load(typed_name)
44     else
45       @last_result
46     end
47   end
48 end
loaded_entry(typed_name, check_dependencies = false) click to toggle source

@api public

   # File lib/puppet/pops/loader/base_loader.rb
52 def loaded_entry(typed_name, check_dependencies = false)
53   synchronize do
54     if @named_values.has_key?(typed_name)
55       @named_values[typed_name]
56     elsif parent
57       parent.loaded_entry(typed_name, check_dependencies)
58     else
59       nil
60     end
61   end
62 end
promote_entry(named_entry) click to toggle source

Promotes an already created entry (typically from another loader) to this loader

@api private

    # File lib/puppet/pops/loader/base_loader.rb
116 def promote_entry(named_entry)
117   synchronize do
118     typed_name = named_entry.typed_name
119     entry = @named_values[typed_name]
120     if entry then fail_redefine(entry); end
121     @named_values[typed_name] = named_entry
122   end
123 end
remove_entry(typed_name) click to toggle source

@api private

    # File lib/puppet/pops/loader/base_loader.rb
104 def remove_entry(typed_name)
105   synchronize do
106     unless @named_values.delete(typed_name).nil?
107       @last_result = nil unless @last_result.nil? || typed_name != @last_result.typed_name
108     end
109   end
110 end
set_entry(typed_name, value, origin = nil) click to toggle source

@api private

   # File lib/puppet/pops/loader/base_loader.rb
74 def set_entry(typed_name, value, origin = nil)
75   synchronize do
76     # It is never ok to redefine in the very same loader unless redefining a 'not found'
77     entry = @named_values[typed_name]
78     if entry
79       fail_redefine(entry) unless entry.value.nil?
80     end
81 
82     # Check if new entry shadows existing entry and fail
83     # (unless special loader allows shadowing)
84     if typed_name.type == :type && !allow_shadowing?
85       entry = loaded_entry(typed_name)
86       if entry
87         fail_redefine(entry) unless entry.value.nil? #|| entry.value == value
88       end
89     end
90 
91     @last_result = Loader::NamedEntry.new(typed_name, value, origin)
92     @named_values[typed_name] = @last_result
93   end
94 end

Protected Instance Methods

allow_shadowing?() click to toggle source
    # File lib/puppet/pops/loader/base_loader.rb
127 def allow_shadowing?
128   false
129 end

Private Instance Methods

fail_redefine(entry) click to toggle source
    # File lib/puppet/pops/loader/base_loader.rb
133 def fail_redefine(entry)
134   origin_info = entry.origin ? _("Originally set %{original}.") % { original: origin_label(entry.origin) } : _("Set at unknown location")
135   raise ArgumentError, _("Attempt to redefine entity '%{name}'. %{origin_info}") % { name: entry.typed_name, origin_info: origin_info }
136 end
format_uri(uri) click to toggle source
    # File lib/puppet/pops/loader/base_loader.rb
150 def format_uri(uri)
151   (uri.scheme == 'puppet' ? 'by ' : 'at ') + uri.to_s.sub(/^puppet:/,'')
152 end
internal_load(typed_name) click to toggle source

loads in priority order:

  1. already loaded here

  2. load from parent

  3. find it here

  4. give up

    # File lib/puppet/pops/loader/base_loader.rb
160 def internal_load(typed_name)
161   # avoid calling get_entry by looking it up
162   te = @named_values[typed_name]
163   return te unless te.nil? || te.value.nil?
164 
165   te = parent.load_typed(typed_name)
166   return te unless te.nil? || te.value.nil?
167 
168   # Under some circumstances, the call to the parent loader will have resulted in files being
169   # parsed that in turn contained references to the requested entity and hence, caused a
170   # recursive call into this loader. This means that the entry might be present now, so a new
171   # check must be made.
172   te = @named_values[typed_name]
173   te.nil? || te.value.nil? ? find(typed_name) : te
174 end
origin_label(origin) click to toggle source

TODO: Should not really be here?? - TODO: A Label provider ? semantics for the URI?

    # File lib/puppet/pops/loader/base_loader.rb
140 def origin_label(origin)
141   if origin && origin.is_a?(URI)
142     format_uri(origin)
143   elsif origin.respond_to?(:uri)
144     format_uri(origin.uri)
145   else
146     origin
147   end
148 end