+1

On Jul 26, 2009, at 9:03 AM, Brice Figureau wrote:

>
> Those variables have been created to be short lived and used mainly
> to define temporary special variables.
> They do not persist after a call to unset_ephemeral_var.
> Also Scope#set_ephemeral_from can be used to promote a regexp
> MatchData to ephemeral values.
>
> Signed-off-by: Brice Figureau <[email protected]>
> ---
> lib/puppet/parser/ast/vardef.rb |    2 +-
> lib/puppet/parser/scope.rb      |   61 +++++++++++++++++++++++ 
> +----------
> spec/unit/parser/ast/vardef.rb  |    4 +-
> spec/unit/parser/scope.rb       |   68 ++++++++++++++++++++++++++++++ 
> +++++----
> 4 files changed, 107 insertions(+), 28 deletions(-)
>
> diff --git a/lib/puppet/parser/ast/vardef.rb b/lib/puppet/parser/ast/ 
> vardef.rb
> index 2d5f623..ae24b32 100644
> --- a/lib/puppet/parser/ast/vardef.rb
> +++ b/lib/puppet/parser/ast/vardef.rb
> @@ -17,7 +17,7 @@ class Puppet::Parser::AST
>             value = @value.safeevaluate(scope)
>
>             parsewrap do
> -                scope.setvar(name,value, @file, @line, @append)
> +                scope.setvar(name,value, :file => @file, :line =>  
> @line, :append => @append)
>             end
>         end
>
> diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
> index be4dc12..5b3c6d0 100644
> --- a/lib/puppet/parser/scope.rb
> +++ b/lib/puppet/parser/scope.rb
> @@ -128,6 +128,11 @@ class Puppet::Parser::Scope
>         # The symbol table for this scope.  This is where we store  
> variables.
>         @symtable = {}
>
> +        # the ephemeral symbol tables
> +        # those should not persist long, and are used for the  
> moment only
> +        # for $0..$xy capture variables of regexes
> +        @ephemeral = {}
> +
>         # All of the defaults set for types.  It's a hash of hashes,
>         # with the first key being the type, then the second key being
>         # the parameter.
> @@ -189,16 +194,17 @@ class Puppet::Parser::Scope
>     # Look up a variable.  The simplest value search we do.  Default  
> to returning
>     # an empty string for missing values, but support returning a  
> constant.
>     def lookupvar(name, usestring = true)
> +        table = ephemeral?(name) ? @ephemeral : @symtable
>         # If the variable is qualified, then find the specified  
> scope and look the variable up there instead.
>         if name =~ /::/
>             return lookup_qualified_var(name, usestring)
>         end
> -        # We can't use "if @symtable[name]" here because the value  
> might be false
> -        if @symtable.include?(name)
> -            if usestring and @symtable[name] == :undef
> +        # We can't use "if table[name]" here because the value  
> might be false
> +        if table.include?(name)
> +            if usestring and table[name] == :undef
>                 return ""
>             else
> -                return @symtable[name]
> +                return table[name]
>             end
>         elsif self.parent
>             return parent.lookupvar(name, usestring)
> @@ -286,34 +292,35 @@ class Puppet::Parser::Scope
>     # Set a variable in the current scope.  This will override  
> settings
>     # in scopes above, but will not allow variables in the current  
> scope
>     # to be reassigned.
> -    def setvar(name,value, file = nil, line = nil, append = false)
> +    def setvar(name,value, options = {})
> +        table = options[:ephemeral] ? @ephemeral : @symtable
>         #Puppet.debug "Setting %s to '%s' at level %s mode append  
> %s" %
>         #    [name.inspect,value,self.level, append]
> -        if @symtable.include?(name)
> -            unless append
> +        if table.include?(name)
> +            unless options[:append]
>                 error = Puppet::ParseError.new("Cannot reassign  
> variable %s" % name)
>             else
>                 error = Puppet::ParseError.new("Cannot append,  
> variable %s is defined in this scope" % name)
>             end
> -            if file
> -                error.file = file
> +            if options[:file]
> +                error.file = options[:file]
>             end
> -            if line
> -                error.line = line
> +            if options[:line]
> +                error.line = options[:line]
>             end
>             raise error
>         end
>
> -        unless append
> -            @symtable[name] = value
> +        unless options[:append]
> +            table[name] = value
>         else # append case
>             # lookup the value in the scope if it exists and insert  
> the var
> -            @symtable[name] = lookupvar(name)
> +            table[name] = lookupvar(name)
>             # concatenate if string, append if array, nothing for  
> other types
>             if value.is_a?(Array)
> -                @symtable[name] += value
> +                table[name] += value
>             else
> -                @symtable[name] << value
> +                table[name] << value
>             end
>         end
>     end
> @@ -391,8 +398,26 @@ class Puppet::Parser::Scope
>
>     # Undefine a variable; only used for testing.
>     def unsetvar(var)
> -        if @symtable.include?(var)
> -            @symtable.delete(var)
> +        table = ephemeral?(var) ? @ephemeral : @table
> +        if table.include?(var)
> +            table.delete(var)
> +        end
> +    end
> +
> +    def unset_ephemeral_var
> +        @ephemeral = {}
> +    end
> +
> +    def ephemeral?(name)
> +        @ephemeral.include?(name)
> +    end
> +
> +    def ephemeral_from(match, file = nil, line = nil)
> +        raise(ArgumentError,"Invalid regex match data") unless  
> match.is_a?(MatchData)
> +
> +        setvar("0", match[0], :file => file, :line =>  
> line, :ephemeral => true)
> +        match.captures.each_with_index do |m,i|
> +            setvar("#{i+1}", m, :file => file, :line =>  
> line, :ephemeral => true)
>         end
>     end
> end
> diff --git a/spec/unit/parser/ast/vardef.rb b/spec/unit/parser/ast/ 
> vardef.rb
> index 14de689..9730cee 100755
> --- a/spec/unit/parser/ast/vardef.rb
> +++ b/spec/unit/parser/ast/vardef.rb
> @@ -25,7 +25,7 @@ describe Puppet::Parser::AST::VarDef do
>             name = stub 'name', :safeevaluate => "var"
>             value = stub 'value', :safeevaluate => "1"
>
> -            @scope.expects(:setvar).with { | 
> name,value,file,line,append| append == nil }
> +            @scope.expects(:setvar).with { |name,value,options|  
> options[:append] == nil }
>
>             vardef = Puppet::Parser::AST::VarDef.new :name =>  
> name, :value => value, :file => nil,
>                                                      :line => nil
> @@ -36,7 +36,7 @@ describe Puppet::Parser::AST::VarDef do
>             name = stub 'name', :safeevaluate => "var"
>             value = stub 'value', :safeevaluate => "1"
>
> -            @scope.expects(:setvar).with { | 
> name,value,file,line,append| append == true }
> +            @scope.expects(:setvar).with { |name,value,options|  
> options[:append] == true }
>
>             vardef = Puppet::Parser::AST::VarDef.new :name =>  
> name, :value => value, :file => nil,
>                                                      :line =>  
> nil, :append => true
> diff --git a/spec/unit/parser/scope.rb b/spec/unit/parser/scope.rb
> index a9784e0..641a3f9 100755
> --- a/spec/unit/parser/scope.rb
> +++ b/spec/unit/parser/scope.rb
> @@ -111,24 +111,24 @@ describe Puppet::Parser::Scope do
>
>     describe "when setvar is called with append=true" do
>         it "should raise error if the variable is already defined in  
> this scope" do
> -            @scope.setvar("var","1",nil,nil,false)
> -            lambda { @scope.setvar("var","1",nil,nil,true) }.should  
> raise_error(Puppet::ParseError)
> +            @scope.setvar("var","1", :append => false)
> +            lambda { @scope.setvar("var","1", :append =>  
> true) }.should raise_error(Puppet::ParseError)
>         end
>
>         it "it should lookup current variable value" do
>             @scope.expects(:lookupvar).with("var").returns("2")
> -            @scope.setvar("var","1",nil,nil,true)
> +            @scope.setvar("var","1", :append => true)
>         end
>
>         it "it should store the concatenated string '42'" do
> -            @topscope.setvar("var","4",nil,nil,false)
> -            @scope.setvar("var","2",nil,nil,true)
> +            @topscope.setvar("var","4", :append => false)
> +            @scope.setvar("var","2", :append => true)
>             @scope.lookupvar("var").should == "42"
>         end
>
>         it "it should store the concatenated array [4,2]" do
> -            @topscope.setvar("var",[4],nil,nil,false)
> -            @scope.setvar("var",[2],nil,nil,true)
> +            @topscope.setvar("var",[4], :append => false)
> +            @scope.setvar("var",[2], :append => true)
>             @scope.lookupvar("var").should == [4,2]
>         end
>
> @@ -195,4 +195,58 @@ describe Puppet::Parser::Scope do
>             Puppet::Parser::Scope.number?("0x89g").should be_nil
>         end
>     end
> +
> +    describe "when using ephemeral variables" do
> +        it "should store the variable value" do
> +            @scope.setvar("1", :value, :ephemeral => true)
> +
> +            @scope.lookupvar("1").should == :value
> +        end
> +
> +        it "should remove the variable value when  
> unset_ephemeral_var is called" do
> +            @scope.setvar("1", :value, :ephemeral => true)
> +            @scope.stubs(:parent).returns(nil)
> +
> +            @scope.unset_ephemeral_var
> +
> +            @scope.lookupvar("1", false).should == :undefined
> +        end
> +
> +        it "should not remove classic variables when  
> unset_ephemeral_var is called" do
> +            @scope.setvar("myvar", :value1)
> +            @scope.setvar("1", :value2, :ephemeral => true)
> +            @scope.stubs(:parent).returns(nil)
> +
> +            @scope.unset_ephemeral_var
> +
> +            @scope.lookupvar("myvar", false).should == :value1
> +        end
> +    end
> +
> +    describe "when setting ephemeral vars from matches" do
> +        before :each do
> +            @match = stub 'match', :is_a? => true
> +            @match.stubs(:[]).with(0).returns("this is a string")
> +            @match.stubs(:captures).returns([])
> +            @scope.stubs(:setvar)
> +        end
> +
> +        it "should accept only MatchData" do
> +            lambda { @scope.ephemeral_from("match") }.should  
> raise_error
> +        end
> +
> +        it "should set $0 with the full match" do
> +            @scope.expects(:setvar).with { |*arg| arg[0] == "0" and  
> arg[1] == "this is a string" and arg[2][:ephemeral] }
> +
> +            @scope.ephemeral_from(@match)
> +        end
> +
> +        it "should set every capture as ephemeral var" do
> +            @match.stubs(:captures).returns([:capture1,:capture2])
> +            @scope.expects(:setvar).with { |*arg| arg[0] == "1" and  
> arg[1] == :capture1 and arg[2][:ephemeral] }
> +            @scope.expects(:setvar).with { |*arg| arg[0] == "2" and  
> arg[1] == :capture2 and arg[2][:ephemeral] }
> +
> +            @scope.ephemeral_from(@match)
> +        end
> +    end
> end
> -- 
> 1.6.0.2
>
>
> >


-- 
Discovery consists of seeing what everybody has seen and thinking what
nobody has thought. -- Albert Szent-Gyorgyi
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com


--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to