Class: Puppet::Pops::Loader::RubyLegacyFunctionInstantiator

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb

Constant Summary collapse

UNKNOWN =
'<unknown>'

Class Method Summary collapse

Class Method Details

.create(loader, typed_name, source_ref, ruby_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 ruby source does not produce this instance when evaluated.

Parameters:

  • loader (Puppet::Pops::Loader::Loader)

    The loader the function is associated with

  • typed_name (Puppet::Pops::Loader::TypedName)

    the type / name of the function to load

  • source_ref (URI, String)

    a reference to the source / origin of the ruby code to evaluate

  • ruby_code_string (String)

    ruby code in a string

Returns:

  • (Puppet::Pops::Functions.Function)
    • an instantiated function with global scope closure associated with the given loader

 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 58 59 60 61 62 63 64 65 66
# File 'lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb', line 20 def self.create(loader, typed_name, source_ref, ruby_code_string) # Assert content of 3x function by parsing  assertion_result = [] if assert_code(ruby_code_string, source_ref, assertion_result) unless ruby_code_string.is_a?(String) && assertion_result.include?(:found_newfunction) raise ArgumentError, _("The code loaded from %{source_ref} does not seem to be a Puppet 3x API function - no 'newfunction' call.") % { source_ref: source_ref } end end # make the private loader available in a binding to allow it to be passed on  loader_for_function = loader.private_loader here = get_binding(loader_for_function) # Avoid reloading the function if already loaded via one of the APIs that trigger 3x function loading  # Check if function is already loaded the 3x way (and obviously not the 4x way since we would not be here in the  # first place.  environment = Puppet.lookup(:current_environment) func_info = Puppet::Parser::Functions.environment_module(environment).get_function_info(typed_name.name.to_sym) if func_info.nil? # This will do the 3x loading and define the "function_<name>" and "real_function_<name>" methods  # in the anonymous module used to hold function definitions.  #  func_info = eval(ruby_code_string, here, source_ref, 1) # rubocop:disable Security/Eval  # Validate what was loaded  unless func_info.is_a?(Hash) # TRANSLATORS - the word 'newfunction' should not be translated as it is a method name.  raise ArgumentError, _("Illegal legacy function definition! The code loaded from %{source_ref} did not return the result of calling 'newfunction'. Got '%{klass}'") % { source_ref: source_ref, klass: func_info.class } end unless func_info[:name] == "function_#{typed_name.name()}" raise ArgumentError, _("The code loaded from %{source_ref} produced mis-matched name, expected 'function_%{type_name}', got '%{created_name}'") % { source_ref: source_ref, type_name: typed_name.name, created_name: func_info[:name] } end end created = Puppet::Functions::Function3x.create_function(typed_name.name(), func_info, loader_for_function) # 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  # Sets closure scope to nil, to let it be picked up at runtime from Puppet.lookup(:global_scope)  # If function definition used the loader from the binding to create a new loader, that loader wins  created.new(nil, loader_for_function) end