Class: Puppet::Pops::Loader::PuppetFunctionInstantiator
- Defined in:
- lib/puppet/pops/loader/puppet_function_instantiator.rb
Overview
The PuppetFunctionInstantiator instantiates a Puppet::Functions::PuppetFunction given a Puppet Programming language source that when called evaluates the Puppet logic it contains.
Class Method Summary collapse
-
.create(loader, typed_name, source_ref, pp_code_string) ⇒ Puppet::Pops::Functions::Function
Produces an instance of the Function class with the given typed_name, or fails with an error if the given puppet source does not produce this instance when evaluated.
-
.create_from_model(function_definition, loader) ⇒ Array<Puppet::Pops::Loader::Loader::TypedName, Puppet::Pops::Functions.Function>
Creates Function class and instantiates it based on a FunctionDefinition model.
- .create_function_class(function_definition, closure_scope) ⇒ Object
Class Method Details
.create(loader, typed_name, source_ref, pp_code_string) ⇒ Puppet::Pops::Functions::Function
Produces an instance of the Function class with the given typed_name, or fails with an error if the given puppet source does not produce this instance when evaluated.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/puppet/pops/loader/puppet_function_instantiator.rb', line 15 def self.create(loader, typed_name, source_ref, pp_code_string) parser = Puppet::Pops::Parser::EvaluatingParser.new() # parse and validate result = parser.parse_string(pp_code_string, source_ref) # Only one function is allowed (and no other definitions) case result.model.definitions.size when 0 raise ArgumentError, "The code loaded from #{source_ref} does not define the function '#{typed_name.name}' - it is empty." when 1 # ok else raise ArgumentError, "The code loaded from #{source_ref} must contain only the function '#{typed_name.name}' - it has additional definitions." end the_function_definition = result.model.definitions[0] unless the_function_definition.is_a?(Puppet::Pops::Model::FunctionDefinition) raise ArgumentError, "The code loaded from #{source_ref} does not define the function '#{typed_name.name}' - no function found." end unless the_function_definition.name == typed_name.name expected = typed_name.name actual = the_function_definition.name raise ArgumentError, "The code loaded from #{source_ref} produced function with the wrong name, expected #{expected}, actual #{actual}" end unless result.model().body == the_function_definition raise ArgumentError, "The code loaded from #{source_ref} contains additional logic - can only contain the function #{typed_name.name}" end # Adapt the function definition with loader - this is used from logic contained in it body to find the # loader to use when making calls to the new function API. Such logic have a hard time finding the closure (where # the loader is known - hence this mechanism Puppet::Pops::Adapters::LoaderAdapter.adapt(the_function_definition).loader = loader # TODO: Cheating wrt. scope - assuming it is found in the context closure_scope = Puppet.lookup(:global_scope) { {} } created = create_function_class(the_function_definition, closure_scope) # create the function instance - it needs closure (scope), and loader (i.e. where it should start searching for things # when calling functions etc. # It should be bound to global scope created.new(closure_scope, loader) end |
.create_from_model(function_definition, loader) ⇒ Array<Puppet::Pops::Loader::Loader::TypedName, Puppet::Pops::Functions.Function>
Creates Function class and instantiates it based on a FunctionDefinition model
63 64 65 66 67 68 |
# File 'lib/puppet/pops/loader/puppet_function_instantiator.rb', line 63 def self.create_from_model(function_definition, loader) closure_scope = Puppet.lookup(:global_scope) { {} } created = create_function_class(function_definition, closure_scope) typed_name = Puppet::Pops::Loader::Loader::TypedName.new(:function, function_definition.name) [typed_name, created.new(closure_scope, loader)] end |
.create_function_class(function_definition, closure_scope) ⇒ Object
70 71 72 73 74 75 76 77 |
# File 'lib/puppet/pops/loader/puppet_function_instantiator.rb', line 70 def self.create_function_class(function_definition, closure_scope) # Create a 4x function wrapper around a named closure Puppet::Functions.create_function(function_definition.name, Puppet::Functions::PuppetFunction) do init_dispatch(Puppet::Pops::Evaluator::Closure::Named.new( function_definition.name, Puppet::Pops::Evaluator::EvaluatorImpl.new(), function_definition, closure_scope)) end end |