* Implement Puppet::Parser::Scope#each_var to yield all variables and values
within
the current scope, and optionally into the parent.
* Use that to set instance member variables into
Puppet::Parser::Templatewrapper
* Rename the @scope member of the template wrapper, to avoid clashing with a
scope
variable exposed within puppet.
Signed-off-by: Daniel Pittman <[EMAIL PROTECTED]>
---
lib/puppet/parser/scope.rb | 12 ++++++++++++
lib/puppet/parser/templatewrapper.rb | 31 +++++++++++++++++++++++--------
2 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index a6e43e7..6b28546 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -183,6 +183,18 @@ class Puppet::Parser::Scope
end
end
+ # Enumerate all variables, yielding their names and values. Used to
+ # expose variables to the ERB template system. By default, recursive, so
+ # returns all parent scope variables before current scope variables, but
+ # that can be disabled.
+ def each_var recursive = true
+ if recursive and parent then
+ parent.each_var(recursive) { |name, value| yield(name, value) }
+ end
+ @symtable.each { |name, value| yield(name, value) }
+ return self
+ end
+
def namespaces
@namespaces.dup
end
diff --git a/lib/puppet/parser/templatewrapper.rb
b/lib/puppet/parser/templatewrapper.rb
index 4790cea..f95a292 100644
--- a/lib/puppet/parser/templatewrapper.rb
+++ b/lib/puppet/parser/templatewrapper.rb
@@ -6,8 +6,8 @@ class Puppet::Parser::TemplateWrapper
Puppet::Util.logmethods(self)
def initialize(scope, file)
- @scope = scope
- @file = Puppet::Module::find_template(file,
@scope.compiler.environment)
+ @__scope__ = scope
+ @file = Puppet::Module::find_template(file,
@__scope__.compiler.environment)
unless FileTest.exists?(@file)
raise Puppet::ParseError,
@@ -15,26 +15,41 @@ class Puppet::Parser::TemplateWrapper
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.
+ scope.each_var { |name, value| instance_variable_set("@#{name}",
value) }
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
--
1.5.4.3
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---