diff options
| author | Brice Figureau <brice-puppet@daysofwonder.com> | 2010-02-08 20:17:38 +0100 |
|---|---|---|
| committer | James Turnbull <james@lovedthanlost.net> | 2010-03-25 16:20:52 +1100 |
| commit | 5d10f65745ce78e71e9a4cfce7f1f60c45db2501 (patch) | |
| tree | 89b8723c1894ced7732cf298e797052e3021f8f1 /lib/puppet/parser/ast | |
| parent | fbedb999e4f4cc8020bc6be4a1d8868368c3ed7f (diff) | |
Fix #3155 - prevent error when using two matching regex in cascade
The following manifest:
case $var {
/match/: {
if $var =~ /matchagain/ {
}
}
}
is failing because the "=~" operators when matching sets an ephemeral
variable in the scope. But the case regex also did it, and since they
both belong to the same scope, and Puppet variables are immutables, the
scope raises an error.
This patch fixes this issue by adding to the current scope a stack
of ephemeral symbol tables. Each new match operator or case/selector
with regex adds a new scope. When we get out of the case/if/selector
structure the scope is reset to the ephemeral level we were when
entering it.
This way the following manifest produces the correct output:
case $var {
/match(rematch)/: {
notice("1. \$0 = $0, \$1 = $1")
if $var =~ /matchagain/ {
notice("2. \$0 = $0, \$1 = $1")
}
notice("3. \$0 = $0, \$1 = $1")
}
}
notice("4. \$0 = $0")
And the output is:
1. $0 = match, $1 = rematch
2. $0 = matchagain, $1 = rematch
3. $0 = match, $1 = rematch
4. $0 =
Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
Diffstat (limited to 'lib/puppet/parser/ast')
| -rw-r--r-- | lib/puppet/parser/ast/casestatement.rb | 4 | ||||
| -rw-r--r-- | lib/puppet/parser/ast/ifstatement.rb | 3 | ||||
| -rw-r--r-- | lib/puppet/parser/ast/selector.rb | 3 |
3 files changed, 7 insertions, 3 deletions
diff --git a/lib/puppet/parser/ast/casestatement.rb b/lib/puppet/parser/ast/casestatement.rb index 64298cac3..ed1bb8aa3 100644 --- a/lib/puppet/parser/ast/casestatement.rb +++ b/lib/puppet/parser/ast/casestatement.rb @@ -11,6 +11,8 @@ class Puppet::Parser::AST # Short-curcuit evaluation. Return the value of the statements for # the first option that matches. def evaluate(scope) + level = scope.ephemeral_level + value = @test.safeevaluate(scope) retvalue = nil @@ -32,7 +34,7 @@ class Puppet::Parser::AST Puppet.debug "No true answers and no default" return nil ensure - scope.unset_ephemeral_var + scope.unset_ephemeral_var(level) end def each diff --git a/lib/puppet/parser/ast/ifstatement.rb b/lib/puppet/parser/ast/ifstatement.rb index 9d52123b6..d84445bbd 100644 --- a/lib/puppet/parser/ast/ifstatement.rb +++ b/lib/puppet/parser/ast/ifstatement.rb @@ -16,6 +16,7 @@ class Puppet::Parser::AST # else if there's an 'else' setting, evaluate it. # the first option that matches. def evaluate(scope) + level = scope.ephemeral_level value = @test.safeevaluate(scope) # let's emulate a new scope for each branches @@ -30,7 +31,7 @@ class Puppet::Parser::AST end end ensure - scope.unset_ephemeral_var + scope.unset_ephemeral_var(level) end end end diff --git a/lib/puppet/parser/ast/selector.rb b/lib/puppet/parser/ast/selector.rb index ce834b63b..cc468a536 100644 --- a/lib/puppet/parser/ast/selector.rb +++ b/lib/puppet/parser/ast/selector.rb @@ -12,6 +12,7 @@ class Puppet::Parser::AST # Find the value that corresponds with the test. def evaluate(scope) + level = scope.ephemeral_level # Get our parameter. paramvalue = @param.safeevaluate(scope) @@ -37,7 +38,7 @@ class Puppet::Parser::AST self.fail Puppet::ParseError, "No matching value for selector param '%s'" % paramvalue ensure - scope.unset_ephemeral_var + scope.unset_ephemeral_var(level) end def to_s |
