Producer is an abstract base class representing the base contract for a bound producer. Typically, when a lookup is performed it is the value that is returned (via a producer), but it is also possible to lookup the producer, and ask it to produce the value (the producer may return a series of values, which makes this especially useful).
When looking up a producer, it is of importance to only use the API of the Producer class unless it is known that a particular custom producer class has been bound.
Custom Producers
The intent is that this class is derived for custom producers that require additional options/arguments when producing an instance. Such a custom producer may raise an error if called with too few arguments, or may implement specific `produce` methods and always raise an error on produce indicating that this producer requires custom calls and that it can not be used as an implicit producer.
Features of Producer
The Producer class is abstract, but offers the ability to transform the produced result by passing the option `:transformer` which should be a Puppet Lambda Expression taking one argument and producing the transformed (wanted) result.
@abstract @api public
A Puppet 3 AST Lambda Expression @api public
Produces an instance. @param scope [Puppet::Parser:Scope] the scope to use for evaluation @param args [Object] arguments to custom producers, always empty for implicit productions @return [Object] the produced instance (should never be nil). @api public
# File lib/puppet/pops/binder/producers.rb, line 76 def produce(scope, *args) do_transformation(scope, internal_produce(scope)) end
Returns the producer after possibly having recreated an internal/wrapped producer. This implementation returns `self`. A derived class may want to override this method to perform initialization/refresh of its internal state. This method is called when a producer is requested. @see Puppet::Pops::Binder::ProducerProducer for an example of implementation. @param scope [Puppet::Parser:Scope] the scope to use for evaluation @return [Puppet::Pops::Binder::Producer] the producer to use @api public
# File lib/puppet/pops/binder/producers.rb, line 89 def producer(scope) self end
Transforms the produced value if a transformer has been defined. @param scope [Puppet::Parser::Scope] the scope used for evaluation @param produced_value [Object, nil] the produced value (possibly nil) @return [Object] the transformed value if a transformer is defined, else the given `produced_value` @api private
# File lib/puppet/pops/binder/producers.rb, line 111 def do_transformation(scope, produced_value) return produced_value unless transformer transformer.call(produced_value) end
Derived classes should implement this method to do the production of a value @param scope [Puppet::Parser::Scope] the scope to use when performing lookup and evaluation @raise [NotImplementedError] this implementation always raises an error @abstract @api private
# File lib/puppet/pops/binder/producers.rb, line 101 def internal_produce(scope) raise NotImplementedError, "Producer-class '#{self.class.name}' should implement #internal_produce(scope)" end
Creates a Producer. Derived classes should call this constructor to get support for transformer lambda.
@param injector [Puppet::Pops::Binder::Injector] The injector where the lookup originates @param binding [Puppet::Pops::Binder::Bindings::Binding, nil] The binding using this producer @param scope [Puppet::Parser::Scope] The scope to use for evaluation @option options [Puppet::Pops::Model::LambdaExpression] :transformer (nil) a transformer of produced value @api public
# File lib/puppet/pops/binder/producers.rb, line 57 def initialize(injector, binding, scope, options) if transformer_lambda = options[:transformer] if transformer_lambda.is_a?(Proc) raise ArgumentError, "Transformer Proc must take one argument; value." unless transformer_lambda.arity == 1 @transformer = transformer_lambda else raise ArgumentError, "Transformer must be a LambdaExpression" unless transformer_lambda.is_a?(Puppet::Pops::Model::LambdaExpression) raise ArgumentError, "Transformer lambda must take one argument; value." unless transformer_lambda.parameters.size() == 1 @transformer = Puppet::Pops::Parser::EvaluatingParser.new.closure(transformer_lambda, scope) end end end