On Jul 5, 2011, at 2:12 PM, R.I.Pienaar wrote:
>
>
> ----- Original Message -----
>> On Jul 5, 2011, at 1:37 PM, Brice Figureau wrote:
>>
>>> On 05/07/11 21:36, Luke Kanies wrote:
>>>> This is primarily two changes:
>>>>
>>>> * Add [] and []= to Puppet::Parser::Scope
>>>> * Replace lookupvar/setvar usage with those two methods
>>>>
>>>> The first was pretty simple, but the second ended up touching a
>>>> lot of files.
>>>
>>> What's the underlying purpose (ie the big plan behind) of those
>>> changes?
>>
>> Hiera (Arri's extlookup replacement) needs Scope to have hash-like
>> behavior, and this is to provide that.
>>
>> Once I added the methods, I realized how ugly the existing methods
>> were, and it made sense to clean the whole thing up from there.
>>
>> Sorry, that should have been in my commit - I'll fix that.
>
> I think hiera aside this is a great improvement, it behaves more ruby like
> and less surprising, scope will just work how people who know ruby would think
> it would work and thats a big win.
>
> If in a template using foo would return nil if its unset that would be a
> big win too, means has_variable?("foo") can go away, not sure how related that
> is to your refactor though.
It's not necessarily related, but since I've got the whole thing swapped in...
Since we've got the 'include?' method now, and returning :undefined is not very
ruby-like, I ran through and made some further changes in behavior. Now the []
method returns nil for unknown values (instead of :undefined), and anything
that was previously testing for :undefined now tests scope.include?(var).
This provides the same behavior with much more ruby-like semantics and minimal
(but non-zero) incompatibility.
Here's the patch, and I've pushed it to the end of the series I published
earlier:
commit fee303d7dfdcc2381eb8b2fc4a33a2924461c561
Author: Luke Kanies <[email protected]>
Date: Tue Jul 5 16:32:03 2011 -0700
Scope[] now returns nil for undefined variables
Any code that previously checked whether lookupvar
(or the new []) returned :undefined should now check
whether 'scope.include?(var)'. Thus, you can have
the same behavior, but it takes a bit different code
to get it.
Signed-off-by: Luke Kanies <[email protected]>
diff --git a/lib/puppet/parser/ast/leaf.rb b/lib/puppet/parser/ast/leaf.rb
index 64a1974..3efb52f 100644
--- a/lib/puppet/parser/ast/leaf.rb
+++ b/lib/puppet/parser/ast/leaf.rb
@@ -124,10 +124,11 @@ class Puppet::Parser::AST
# not include syntactical constructs, like '$' and '{}').
def evaluate(scope)
parsewrap do
- if (var = scope[@value, {:file => file, :line => line}]) == :undefined
- var = :undef
+ if ! scope.include?(@value)
+ :undef
+ else
+ scope[@value, {:file => file, :line => line}]
end
- var
end
end
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index 6b072bd..56887c3 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -258,7 +258,8 @@ class Puppet::Parser::Resource < Puppet::Resource
def add_backward_compatible_relationship_param(name)
# Skip metaparams for which we get no value.
- return unless val = scope[name.to_s] and val != :undefined
+ return unless scope.include?(name.to_s)
+ val = scope[name.to_s]
# The default case: just set the value
set_parameter(name, val) and return unless @parameters[name]
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index 3a87f96..9d84c7e 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -57,7 +57,7 @@ class Puppet::Parser::Scope
rescue RuntimeError => e
location = (options[:file] && options[:line]) ? " at
#{options[:file]}:#{options[:line]}" : ''
warning "Could not look up qualified variable '#{name}';
#{e.message}#{location}"
- :undefined
+ nil
end
elsif ephemeral_include?(name) or table.include?(name)
# We can't use "if table[name]" here because the value might be false
@@ -69,7 +69,7 @@ class Puppet::Parser::Scope
elsif parent
parent[name,options.merge(:dynamic => (dynamic || options[:dynamic]))]
else
- :undefined
+ nil
end
end
@@ -92,7 +92,7 @@ class Puppet::Parser::Scope
end
def include?(name)
- self[name] != :undefined
+ ! self[name].nil?
end
# Is the value true? This allows us to control the definition of truth
@@ -244,7 +244,11 @@ class Puppet::Parser::Scope
end
def undef_as(x,v)
- (v == :undefined) ? x : (v == :undef) ? x : v
+ if v.nil? or v == :undef
+ x
+ else
+ v
+ end
end
def qualified_scope(classname)
diff --git a/lib/puppet/parser/templatewrapper.rb
b/lib/puppet/parser/templatewrapper.rb
index 83d18cc..9336e70 100644
--- a/lib/puppet/parser/templatewrapper.rb
+++ b/lib/puppet/parser/templatewrapper.rb
@@ -25,7 +25,7 @@ class Puppet::Parser::TemplateWrapper
# Should return true if a variable is defined, false if it is not
def has_variable?(name)
- scope[name.to_s, {:file => file, :line => script_line}] != :undefined
+ scope.include?(name.to_s)
end
# Allow templates to access the defined classes
@@ -56,9 +56,8 @@ class Puppet::Parser::TemplateWrapper
# the missing_method definition here until we declare the syntax finally
# dead.
def method_missing(name, *args)
- value = scope[name.to_s, {:file => file,:line => script_line}]
- if value != :undefined
- return value
+ if scope.include?(name.to_s)
+ return scope[name.to_s, {:file => file,:line => script_line}]
else
# Just throw an error immediately, instead of searching for
# other missingmethod things or whatever.
diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb
index d3ea8df..3c0d15c 100755
--- a/spec/unit/parser/scope_spec.rb
+++ b/spec/unit/parser/scope_spec.rb
@@ -88,8 +88,8 @@ describe Puppet::Parser::Scope do
@scope.lookupvar("var").should == "yep"
end
- it "should return ':undefined' for unset variables" do
- @scope["var"].should == :undefined
+ it "should return nil for unset variables" do
+ @scope["var"].should be_nil
end
it "should be able to look up values" do
@@ -180,32 +180,32 @@ describe Puppet::Parser::Scope do
@scope["other::deep::klass::var"].should == "otherval"
end
- it "should return ':undefined' for qualified variables that cannot be
found in other classes" do
+ it "should return nil for qualified variables that cannot be found in
other classes" do
other_scope = create_class_scope("other::deep::klass")
- @scope["other::deep::klass::var"].should == :undefined
+ @scope["other::deep::klass::var"].should be_nil
end
- it "should warn and return ':undefined' for qualified variables whose
classes have not been evaluated" do
+ it "should warn and return nil for qualified variables whose classes
have not been evaluated" do
klass = newclass("other::deep::klass")
@scope.expects(:warning)
- @scope["other::deep::klass::var"].should == :undefined
+ @scope["other::deep::klass::var"].should be_nil
end
- it "should warn and return ':undefined' for qualified variables whose
classes do not exist" do
+ it "should warn and return nil for qualified variables whose classes do
not exist" do
@scope.expects(:warning)
- @scope["other::deep::klass::var"].should == :undefined
+ @scope["other::deep::klass::var"].should be_nil
end
- it "should return ':undefined' when asked for a non-string qualified
variable from a class that does not exist" do
+ it "should return nil when asked for a non-string qualified variable
from a class that does not exist" do
@scope.stubs(:warning)
- @scope["other::deep::klass::var"].should == :undefined
+ @scope["other::deep::klass::var"].should be_nil
end
- it "should return ':undefined' when asked for a non-string qualified
variable from a class that has not been evaluated" do
+ it "should return nil when asked for a non-string qualified variable
from a class that has not been evaluated" do
@scope.stubs(:warning)
klass = newclass("other::deep::klass")
- @scope["other::deep::klass::var"].should == :undefined
+ @scope["other::deep::klass::var"].should be_nil
end
end
end
@@ -320,7 +320,7 @@ describe Puppet::Parser::Scope do
@scope.unset_ephemeral_var
- @scope["1"].should == :undefined
+ @scope["1"].should be_nil
end
it "should not remove classic variables when unset_ephemeral_var is
called" do
@@ -393,7 +393,7 @@ describe Puppet::Parser::Scope do
@scope.unset_ephemeral_var
- @scope["1"].should == :undefined
+ @scope["1"].should be_nil
end
end
@@ -449,13 +449,13 @@ describe Puppet::Parser::Scope do
it "should be able to unset normal variables" do
@scope["foo"] = "bar"
@scope.unsetvar("foo")
- @scope["foo"].should == :undefined
+ @scope["foo"].should be_nil
end
it "should be able to unset ephemeral variables" do
@scope.setvar("0", "bar", :ephemeral => true)
@scope.unsetvar("0")
- @scope["0"].should == :undefined
+ @scope["0"].should be_nil
end
it "should not unset ephemeral variables in previous ephemeral scope" do
diff --git a/test/language/scope.rb b/test/language/scope.rb
index 57824d8..c80178e 100755
--- a/test/language/scope.rb
+++ b/test/language/scope.rb
@@ -47,7 +47,7 @@ class TestScope < Test::Unit::TestCase
# Now set a var in the midscope and make sure the mid and bottom can see
it but not the top
midscope['second'] = "midval"
- assert_equal(:undefined, scopes[:top]['second'], "Found child var in top
scope")
+ assert_nil(scopes[:top]['second'], "Found child var in top scope")
[:mid, :bot].each do |name|
assert_equal("midval", scopes[name]['second'], "Could not find var in
#{name}")
end
@@ -55,7 +55,7 @@ class TestScope < Test::Unit::TestCase
# And set something in the bottom, and make sure we only find it there.
botscope['third'] = "botval"
[:top, :mid].each do |name|
- assert_equal(:undefined, scopes[name]['third'], "Found child var in top
scope")
+ assert_nil(scopes[name]['third'], "Found child var in top scope")
end
assert_equal("botval", scopes[:bot]['third'], "Could not find var in
bottom scope")
--
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.