The 'closure scope' is the scope the function is defined in.
You can also get access to 'calling scope' by creating a 'system
function' instead of a regular function.
A 'system function' is special as it has more power, but it also comes
with more responsibility.
Ideally functions should not ever need anything but the arguments given
to them. It is good practice to write such pure functions. (i.e.
consider requiring that $module_name is given to the function).
A 'system function' is written like this:
Puppet::Functions.create_function(:inline_epp,
Puppet::Functions::InternalFunction) do
dispatch :inline_epp do
scope_param()
param 'String', :template
optional_param 'Hash[Pattern[/^\w+$/], Any]', :parameters
end
def inline_epp(scope, template, parameters = nil)
Puppet::Pops::Evaluator::EppEvaluator.inline_epp(scope, template,
parameters)
end
end
If you cannot spot it immediately, there are two things you need to do
in your function to make it a 'system function':
* Use create_function(:name, Puppet::Functions::InternalFunction)
instead of just create_functon(:name).
* Make the dispatcher inject the calling scope by calling
'scope_param()' in the dispatchers definition of parameters.
Then, use the calling scope to get the calling scope's variables.
The reason it is bad to directly get variables from a "calling scope" is
that it makes it hard to write general functions. What if you in a
module want to provide a function that wraps calls to a function that
picks up $module_name, or $calling_module from scope?
Thus, use 'InternalFunction' and 'scope_param()' sparingly, if at all.
- henrik
--
Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/