diff options
Diffstat (limited to 'lib/puppet/parser/templatewrapper.rb')
-rw-r--r-- | lib/puppet/parser/templatewrapper.rb | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb index 4790cea30..298428f63 100644 --- a/lib/puppet/parser/templatewrapper.rb +++ b/lib/puppet/parser/templatewrapper.rb @@ -5,36 +5,63 @@ class Puppet::Parser::TemplateWrapper include Puppet::Util Puppet::Util.logmethods(self) - def initialize(scope, file) - @scope = scope - @file = Puppet::Module::find_template(file, @scope.compiler.environment) + def initialize(scope, filename) + @__scope__ = scope + @__file__ = Puppet::Module::find_template(filename, scope.compiler.environment) - unless FileTest.exists?(@file) + unless FileTest.exists?(file) raise Puppet::ParseError, "Could not find template %s" % file end # We'll only ever not have a parser in testing, but, eh. - if @scope.parser - @scope.parser.watch_file(@file) + if scope.parser + scope.parser.watch_file(file) end + + # Expose all the variables in our scope as instance variables of the + # current object, making it possible to access them without conflict + # to the regular methods. + benchmark(:debug, "Bound template variables for #{file}") do + scope.to_hash.each { |name, value| + instance_variable_set("@#{name}", value) + } + end + end + + def scope + @__scope__ + end + + def file + @__file__ end # Should return true if a variable is defined, false if it is not def has_variable?(name) - if @scope.lookupvar(name.to_s, false) != :undefined + if scope.lookupvar(name.to_s, false) != :undefined true else false end end - # Ruby treats variables like methods, so we can cheat here and - # trap missing vars like they were missing methods. + # Ruby treats variables like methods, so we used to expose variables + # within scope to the ERB code via method_missing. As per RedMine #1427, + # though, this means that conflicts between methods in our inheritance + # tree (Kernel#fork) and variable names (fork => "yes/no") could arise. + # + # Worse, /new/ conflicts could pop up when a new kernel or object method + # was added to Ruby, causing templates to suddenly fail mysteriously when + # Ruby was upgraded. + # + # To ensure that legacy templates using unqualified names work we retain + # the missing_method definition here until we declare the syntax finally + # dead. def method_missing(name, *args) # We have to tell lookupvar to return :undefined to us when # appropriate; otherwise it converts to "". - value = @scope.lookupvar(name.to_s, false) + value = scope.lookupvar(name.to_s, false) if value != :undefined return value else @@ -47,8 +74,8 @@ class Puppet::Parser::TemplateWrapper def result result = nil - benchmark(:debug, "Interpolated template #{@file}") do - template = ERB.new(File.read(@file), 0, "-") + benchmark(:debug, "Interpolated template #{file}") do + template = ERB.new(File.read(file), 0, "-") result = template.result(binding) end @@ -56,7 +83,7 @@ class Puppet::Parser::TemplateWrapper end def to_s - "template[%s]" % @file + "template[%s]" % file end end |