Do we also want @file to be @__file__, since it seems fairly likely that
someone will want to use a variable named 'file'?

Thanks for your work on this patch, Daniel - it'll be a big improvement.

You rock.

Adam

On Tue, Jul 22, 2008 at 12:57 AM, Daniel Pittman <[EMAIL PROTECTED]>
wrote:

>
>  * Implement Puppet::Parser::Scope#to_hash, which returns a hash containing
> all the
>   variable bindings in the current and, optionally, parent scope.
>  * Use that to set instance member variables into
> Puppet::Parser::Templatewrapper
>  * Report the time taken for variable binding at debug level, to help
> identify any
>   performance regression that is encountered in the real world.
>  * 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           |   19 ++++++++++++++++
>  lib/puppet/parser/templatewrapper.rb |   39
> +++++++++++++++++++++++++++-------
>  2 files changed, 50 insertions(+), 8 deletions(-)
>
> diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
> index a6e43e7..32b127a 100644
> --- a/lib/puppet/parser/scope.rb
> +++ b/lib/puppet/parser/scope.rb
> @@ -183,6 +183,25 @@ class Puppet::Parser::Scope
>         end
>     end
>
> +    # Return a hash containing our variables and their values, optionally
> (and
> +    # by default) including the values defined in our parent.  Local
> values
> +    # shadow parent values.
> +    def to_hash(recursive = true)
> +        if recursive and parent then
> +            target = parent.to_hash(recursive)
> +        end
> +        target ||= Hash.new
> +        @symtable.keys.each { |name|
> +            value = @symtable[name]
> +            if value == :undef then
> +                target.delete(name)
> +            else
> +                target[name] = value
> +            end
> +        }
> +        return target
> +    end
> +
>     def namespaces
>         @namespaces.dup
>     end
> diff --git a/lib/puppet/parser/templatewrapper.rb
> b/lib/puppet/parser/templatewrapper.rb
> index 4790cea..a517faa 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,49 @@ 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.
> +        benchmark(:debug, "Bound template variables for [EMAIL PROTECTED]") 
> do
> +            scope.to_hash.each { |name, value|
> +                instance_variable_set("@#{name}", value)
> +            }
> +        end
> +    end
> +
> +    def scope
> +        @__scope__
>     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
>
>
> >
>


-- 
HJK Solutions - We Launch Startups - http://www.hjksolutions.com
Adam Jacob, Senior Partner
T: (206) 508-4759 E: [EMAIL PROTECTED]

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