class Puppet::Pops::Loader::RubyFunctionInstantiator

The RubyFunctionInstantiator instantiates a Puppet::Functions::Function given the ruby source that calls Puppet::Functions.create_function.

Public Class Methods

create(loader, typed_name, source_ref, ruby_code_string) click to toggle source

Produces an instance of the Function class with the given typed_name, or fails with an error if the given ruby source does not produce this instance when evaluated.

@param loader [Puppet::Pops::Loader::Loader] The loader the function is associated with @param typed_name [Puppet::Pops::Loader::TypedName] the type / name of the function to load @param source_ref [URI, String] a reference to the source / origin of the ruby code to evaluate @param ruby_code_string [String] ruby code in a string

@return [Puppet::Pops::Functions.Function] - an instantiated function with global scope closure associated with the given loader

   # File lib/puppet/pops/loader/ruby_function_instantiator.rb
16 def self.create(loader, typed_name, source_ref, ruby_code_string)
17   unless ruby_code_string.is_a?(String) && ruby_code_string =~ /Puppet\:\:Functions\.create_function/
18     raise ArgumentError, _("The code loaded from %{source_ref} does not seem to be a Puppet 4x API function - no create_function call.") % { source_ref: source_ref }
19   end
20   # make the private loader available in a binding to allow it to be passed on
21   loader_for_function = loader.private_loader
22   here = get_binding(loader_for_function)
23   created = eval(ruby_code_string, here, source_ref, 1)
24   unless created.is_a?(Class)
25     raise ArgumentError, _("The code loaded from %{source_ref} did not produce a Function class when evaluated. Got '%{klass}'") % { source_ref: source_ref, klass: created.class }
26   end
27   unless created.name.to_s == typed_name.name()
28     raise ArgumentError, _("The code loaded from %{source_ref} produced mis-matched name, expected '%{type_name}', got %{created_name}") % { source_ref: source_ref, type_name: typed_name.name, created_name: created.name }
29   end
30   # create the function instance - it needs closure (scope), and loader (i.e. where it should start searching for things
31   # when calling functions etc.
32   # It should be bound to global scope
33 
34   # Sets closure scope to nil, to let it be picked up at runtime from Puppet.lookup(:global_scope)
35   # If function definition used the loader from the binding to create a new loader, that loader wins
36   created.new(nil, loader_for_function)
37 end

Private Class Methods

get_binding(loader_injected_arg) click to toggle source

Produces a binding where the given loader is bound as a local variable (loader_injected_arg). This variable can be used in loaded ruby code - e.g. to call Puppet::Function.create_loaded_function(:name, loader,…)

   # File lib/puppet/pops/loader/ruby_function_instantiator.rb
42 def self.get_binding(loader_injected_arg)
43   binding
44 end