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

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

Overview

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

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



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
# File 'lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb', line 15

def self.create(loader, typed_name, source_ref, ruby_code_string)
  unless ruby_code_string.is_a?(String) && ruby_code_string =~ /Puppet\:\:Parser\:\:Functions.*newfunction/m
    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
  # 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)

  # This will to 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)

  unless func_info.is_a?(Hash)
    raise ArgumentError, _("The code loaded from %{source_ref} did not produce the expected 3x function info Hash when evaluated. Got '%{klass}'") % { source_ref: source_ref, klass: created.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

  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