(PUP-3548) Allow 4x functions to call 3x functions
The call_function() method of the Puppet::Pops::Functions::Function
class did not make any attempt to find functions that had been
declared using the 3x function API. This commit adds the following:
Proper 3x load and execute:
The call_function() method will now consult the 3x Functions class
to find (and optionally load) the function from there when it fails
to find it using the 4x loader. The load is always performed using
the closure scope of the caller. The 3x load will fail unless the
closure_scope is of type Puppet::Parser::Scope. The scope of the
caller (which might be different from closure_scope) will be the
instance that holds the method that corresponds to the 3x function.
Propagation of caller scope:
The call_function() will pass the closure_scope as that scope of the
caller. In some situations this is not the desired behavior. The
user may want to inject the caller scope, alter it in some way, and
the pass it on as a new caller scope. This commit adds a new API
method to facilitate this:
call_function_with_scope(scope, function_name, *args)
The approach of adding a new method was chosen in favor of adding
an extra scope argument to the existing call_function because in
general, functions should not modify the scope.