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
17 def initialize(parent_loader, loader_name, environment)
18   super(loader_name, environment)
19   @parent = parent_loader # the higher priority loader to consult
20   @named_values = {}      # hash name => NamedEntry
21   @last_result = nil      # the value of the last name (optimization)
22 end

Public Instance Methods

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

@api private

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

@api public

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

@api public

   # File lib/puppet/pops/loader/base_loader.rb
53 def loaded_entry(typed_name, check_dependencies = false)
54   synchronize do
55     if @named_values.has_key?(typed_name)
56       @named_values[typed_name]
57     elsif parent
58       parent.loaded_entry(typed_name, check_dependencies)
59     else
60       nil
61     end
62   end
63 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
117 def promote_entry(named_entry)
118   synchronize do
119     typed_name = named_entry.typed_name
120     entry = @named_values[typed_name]
121     if entry then fail_redefine(entry); end
122     @named_values[typed_name] = named_entry
123   end
124 end
remove_entry(typed_name) click to toggle source

@api private

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

@api private

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

Protected Instance Methods

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

Private Instance Methods

fail_redefine(entry) click to toggle source
    # File lib/puppet/pops/loader/base_loader.rb
134 def fail_redefine(entry)
135   origin_info = entry.origin ? _("Originally set %{original}.") % { original: origin_label(entry.origin) } : _("Set at unknown location")
136   raise ArgumentError, _("Attempt to redefine entity '%{name}'. %{origin_info}") % { name: entry.typed_name, origin_info: origin_info }
137 end
format_uri(uri) click to toggle source
    # File lib/puppet/pops/loader/base_loader.rb
151 def format_uri(uri)
152   (uri.scheme == 'puppet' ? 'by ' : 'at ') + uri.to_s.sub(/^puppet:/,'')
153 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
161 def internal_load(typed_name)
162   # avoid calling get_entry by looking it up
163   te = @named_values[typed_name]
164   return te unless te.nil? || te.value.nil?
165 
166   te = parent.load_typed(typed_name)
167   return te unless te.nil? || te.value.nil?
168 
169   # Under some circumstances, the call to the parent loader will have resulted in files being
170   # parsed that in turn contained references to the requested entity and hence, caused a
171   # recursive call into this loader. This means that the entry might be present now, so a new
172   # check must be made.
173   te = @named_values[typed_name]
174   te.nil? || te.value.nil? ? find(typed_name) : te
175 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
141 def origin_label(origin)
142   if origin && origin.is_a?(URI)
143     format_uri(origin)
144   elsif origin.respond_to?(:uri)
145     format_uri(origin.uri)
146   else
147     origin
148   end
149 end