Class: Puppet::Pops::Binder::Injector

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/pops/binder/injector.rb

Defined Under Namespace

Modules: Private

Constant Summary collapse

Producers =
Producers

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configured_binder, parent_injector = nil) ⇒ Injector

An Injector is initialized with a configured Binder.

Parameters:

  • configured_binder (Binder, nil)

    The configured binder containing effective bindings. A given value of nil creates an injector that returns or yields nil on all lookup requests.

Raises:

  • ArgumentError if the given binder is not fully configured



166
167
168
169
170
171
172
# File 'lib/puppet/pops/binder/injector.rb', line 166

def initialize(configured_binder, parent_injector = nil)
  if configured_binder.nil?
    @impl = Private::NullInjectorImpl.new()
  else
    @impl = Private::InjectorImpl.new(configured_binder, parent_injector)
  end
end

Class Method Details

.create(name, &block) ⇒ Object

Creates an injector with a single bindings layer created with the given name, and the bindings produced by the given block. The block is evaluated with self bound to a BindingsContainerBuilder.

Examples:

Injector.create('mysettings') do
  bind('name').to(42)
end


112
113
114
115
116
# File 'lib/puppet/pops/binder/injector.rb', line 112

def self.create(name, &block)
  factory = BindingsFactory
  layered_bindings = factory.layered_bindings(factory.named_layer(name+'-layer',factory.named_bindings(name, &block).model))
  self.new(Binder.new(layered_bindings))
end

.create_from_hash(name, key_value_hash) ⇒ Object



95
96
97
98
99
100
# File 'lib/puppet/pops/binder/injector.rb', line 95

def self.create_from_hash(name, key_value_hash)
  factory = BindingsFactory
  named_bindings = factory.named_bindings(name) { key_value_hash.each {|k,v| bind.name(k).to(v) }}
  layered_bindings = factory.layered_bindings(factory.named_layer(name+'-layer',named_bindings.model))
  self.new(Binder.new(layered_bindings))
end

.create_from_model(layered_bindings_model) ⇒ Object



91
92
93
# File 'lib/puppet/pops/binder/injector.rb', line 91

def self.create_from_model(layered_bindings_model)
  self.new(Binder.new(layered_bindings_model))
end

.null_injectorObject

Returns an Injector that returns (or yields) nil on all lookups, and produces an empty structure for contributions This method is intended for testing purposes.



339
340
341
# File 'lib/puppet/pops/binder/injector.rb', line 339

def self.null_injector
  self.new(nil)
end

Instance Method Details

#get_contributions(scope, contributions_key) ⇒ Array<InjectorEntry>

Returns the contributions to a multibind given its contribution key (as produced by the KeyFactory). This method is typically used by multibind value producers, but may be used for introspection of the injector’s state.

Parameters:

  • scope (Puppet::Parser::Scope)

    the scope to use

  • contributions_key (Object)

    Opaque key as produced by KeyFactory as the contributions key for a multibinding

Returns:



332
333
334
# File 'lib/puppet/pops/binder/injector.rb', line 332

def get_contributions(scope, contributions_key)
  @impl.get_contributions(scope, contributions_key)
end

#key_factoryKeyFactory

The KeyFactory used to produce keys in this injector. The factory is shared with the Binder to ensure consistent translation to keys. A compatible type calculator can also be obtained from the key factory.

Returns:



181
182
183
# File 'lib/puppet/pops/binder/injector.rb', line 181

def key_factory()
  @impl.key_factory
end

#lookup(scope, key) ⇒ Object #lookup(scope, type, name = '') ⇒ Object #lookup(scope, name) ⇒ Object

Lookup (a.k.a “inject”) of a value given a key. The lookup may be called with different parameters. This method is a convenience method that dispatches to one of #lookup_key or #lookup_type depending on the arguments. It also provides the ability to use an optional block that is called with the looked up value, or scope and value if the block takes two parameters. This is useful to provide a default value or other transformations, calculations based on the result of the lookup.

Overloads:

  • #lookup(scope, key) ⇒ Object

    Parameters:

  • #lookup(scope, type, name = '') ⇒ Object

    Parameters:

    • scope (Puppet::Parser::Scope)

      the scope to use for evaluation

    • type (Types::PAnyType)

      the type of what to lookup

    • name (String) (defaults to: '')

      the name to use, defaults to empty string (for unnamed)

  • #lookup(scope, name) ⇒ Object

    Lookup of Data type with given name.

    Parameters:

    • scope (Puppet::Parser::Scope)

      the scope to use for evaluation

    • name (String)

      the Data/name to lookup

    See Also:

Yields:

  • (value)

    passes the looked up value to an optional block and returns what this block returns

  • (scope, value)

    passes scope and value to the block and returns what this block returns

Yield Parameters:

Raises:

  • (ArgumentError)

    if the block has an arity that is not 1 or 2



228
229
230
# File 'lib/puppet/pops/binder/injector.rb', line 228

def lookup(scope, *args, &block)
  @impl.lookup(scope, *args, &block)
end

#lookup_key(scope, key) ⇒ Object?

Looks up the key and returns the entry, or nil if no entry is found. Produced type is checked for type conformance with its binding, but not with the lookup key. (This since all subtypes of PDataType are looked up using a key based on PDataType). Use the Types::TypeCalculator#instance? method to check for conformance of the result if this is wanted, or use #lookup_type.

Parameters:

  • key (Object)

    lookup of key as produced by the key factory

Returns:

  • (Object, nil)

    produced value of type that conforms with bound type (type conformance with key not guaranteed).

Raises:

  • (ArgumentError)

    if the produced value does not conform with the bound type



261
262
263
# File 'lib/puppet/pops/binder/injector.rb', line 261

def lookup_key(scope, key)
  @impl.lookup_key(scope, key)
end

#lookup_producer(scope, key) ⇒ Producers::Producer, ... #lookup_producer(scope, type, name = '') ⇒ Producers::Producer, ... #lookup_producer(scope, name) ⇒ Producers::Producer, ...

Lookup (a.k.a “inject”) producer of a value given a key. The producer lookup may be called with different parameters. This method is a convenience method that dispatches to one of #lookup_producer_key or #lookup_producer_type depending on the arguments. It also provides the ability to use an optional block that is called with the looked up producer, or scope and producer if the block takes two parameters. This is useful to provide a default value, call a custom producer method, or other transformations, calculations based on the result of the lookup.

Overloads:

Yields:

  • (producer)

    passes the looked up producer to an optional block and returns what this block returns

  • (scope, producer)

    passes scope and producer to the block and returns what this block returns

Yield Parameters:

Returns:

Raises:

  • (ArgumentError)

    if the block has an arity that is not 1 or 2



300
301
302
# File 'lib/puppet/pops/binder/injector.rb', line 300

def lookup_producer(scope, *args, &block)
  @impl.lookup_producer(scope, *args, &block)
end

#lookup_producer_key(scope, key) ⇒ Producers::Producer?

Looks up a Producer given an opaque binder key.

Returns:



309
310
311
# File 'lib/puppet/pops/binder/injector.rb', line 309

def lookup_producer_key(scope, key)
  @impl.lookup_producer_key(scope, key)
end

#lookup_producer_type(scope, type, name = '') ⇒ Producers::Producer?

Note:

The result is not type checked (it cannot be until the producer has produced an instance).

Looks up a Producer given a type/name key.

Returns:



319
320
321
# File 'lib/puppet/pops/binder/injector.rb', line 319

def lookup_producer_type(scope, type, name='')
  @impl.lookup_producer_type(scope, type, name)
end

#lookup_type(scope, type, name = '') ⇒ Object?

Looks up a (typesafe) value based on a type/name combination. Creates a key for the type/name combination using a KeyFactory. Specialization of the Data type are transformed to a Data key, and the result is type checked to conform with the given key.

Parameters:

  • type (Types::PAnyType)

    the type to lookup as defined by Types::TypeFactory

  • name (String) (defaults to: '')

    the (optional for non ‘Data` types) name of the entry to lookup. The name may be an empty String (the default), but not nil. The name is required for lookup for subtypes of `Data`.

Returns:

  • (Object, nil)

    the looked up bound object, or nil if not found (type conformance with given type is guaranteed)

Raises:

  • (ArgumentError)

    if the produced value does not conform with the given type



245
246
247
# File 'lib/puppet/pops/binder/injector.rb', line 245

def lookup_type(scope, type, name='')
  @impl.lookup_type(scope, type, name)
end

#override(name, &block) ⇒ Object

Creates an overriding injector with a single bindings layer created with the given name, and the bindings produced by the given block. The block is evaluated with self bound to a BindingsContainerBuilder.

Examples:

an_injector.override('myoverrides') do
  bind('name').to(43)
end


129
130
131
132
133
# File 'lib/puppet/pops/binder/injector.rb', line 129

def override(name, &block)
  factory = BindingsFactory
  layered_bindings = factory.layered_bindings(factory.named_layer(name+'-layer',factory.named_bindings(name, &block).model))
  self.class.new(Binder.new(layered_bindings, @impl.binder))
end

#override_with_hash(name, key_value_hash) ⇒ Object

Creates an overriding injector with a single bindings layer created with the given name, and the bindings given in the key_value_hash



151
152
153
154
155
156
# File 'lib/puppet/pops/binder/injector.rb', line 151

def override_with_hash(name, key_value_hash)
  factory = BindingsFactory
  named_bindings = factory.named_bindings(name) { key_value_hash.each {|k,v| bind.name(k).to(v) }}
  layered_bindings = factory.layered_bindings(factory.named_layer(name+'-layer',named_bindings.model))
  self.class.new(Binder.new(layered_bindings, @impl.binder))
end

#override_with_model(layered_bindings) ⇒ Object

Creates an overriding injector with bindings from a bindings model (a LayeredBindings) which may consists of multiple layers of bindings.



140
141
142
143
144
145
# File 'lib/puppet/pops/binder/injector.rb', line 140

def override_with_model(layered_bindings)
  unless layered_bindings.is_a?(Bindings::LayeredBindings)
    raise ArgumentError, "Expected a LayeredBindings model, got '#{bindings_model.class}'"
  end
  self.class.new(Binder.new(layered_bindings, @impl.binder))
end

#type_calculatorTypes::TypeCalculator

Returns the TypeCalculator in use for keys. The same calculator (as used for keys) should be used if there is a need to check type conformance, or infer the type of Ruby objects.

Returns:



191
192
193
# File 'lib/puppet/pops/binder/injector.rb', line 191

def type_calculator()
  @impl.type_calculator()
end