summaryrefslogtreecommitdiff
path: root/chef/lib/chef/node
diff options
context:
space:
mode:
authorAdam Jacob <adam@opscode.com>2009-08-08 12:10:10 -0700
committerAJ Christensen <aj@opscode.com>2009-08-10 15:33:05 +1200
commitbb96eba0dbfc17ab0c98a845be645b643dfa9c12 (patch)
tree510652a4e8cfe85feb388005ec87bef1df638a3a /chef/lib/chef/node
parent1a7fd62c3d26606b6e1ed49a362f311f11936010 (diff)
downloadchef-bb96eba0dbfc17ab0c98a845be645b643dfa9c12.tar.gz
Fixing CHEF-473, adding in support for ||= in Chef::Node::Attribute objects
Diffstat (limited to 'chef/lib/chef/node')
-rw-r--r--chef/lib/chef/node/attribute.rb19
1 files changed, 16 insertions, 3 deletions
diff --git a/chef/lib/chef/node/attribute.rb b/chef/lib/chef/node/attribute.rb
index 5f70059a67..1a98e59171 100644
--- a/chef/lib/chef/node/attribute.rb
+++ b/chef/lib/chef/node/attribute.rb
@@ -22,7 +22,7 @@ require 'chef/log'
class Chef
class Node
class Attribute
- attr_accessor :attribute, :default, :override, :state, :current_attribute, :current_default, :current_override, :auto_vivifiy_on_read, :set_unless_value_present
+ attr_accessor :attribute, :default, :override, :state, :current_attribute, :current_default, :current_override, :auto_vivifiy_on_read, :set_unless_value_present, :has_been_read
def initialize(attribute, default, override, state=[])
@attribute = attribute
@@ -34,6 +34,7 @@ class Chef
@state = state
@auto_vivifiy_on_read = false
@set_unless_value_present = false
+ @has_been_read = false
end
# Reset our internal state to the top of every tree
@@ -41,13 +42,17 @@ class Chef
@current_attribute = @attribute
@current_default = @default
@current_override = @override
+ @has_been_read = false
@state = []
end
def [](key)
-
@state << key
+ # We set this to so that we can cope with ||= as a setting.
+ # See the comments in []= for more details.
+ @has_been_read = true
+
o_value = value_or_descend(current_override, key, auto_vivifiy_on_read)
a_value = value_or_descend(current_attribute, key, auto_vivifiy_on_read)
d_value = value_or_descend(current_default, key, auto_vivifiy_on_read)
@@ -170,6 +175,14 @@ class Chef
end
end
+ # If we have been read, and the key we are writing is the same
+ # as our parent, we have most like been ||='ed. So we need to
+ # just rewind a bit.
+ #
+ # In practice, these objects are single use - this is just
+ # supporting one more single-use style.
+ @state.pop if @has_been_read && @state.last == key
+
set_value(@attribute, key, value)
set_value(@override, key, value)
value
@@ -203,7 +216,7 @@ class Chef
def auto_vivifiy(data_hash, key)
if data_hash.has_key?(key)
unless data_hash[key].respond_to?(:has_key?)
- raise ArgumentError, "You tried to set a nested key, where the parent is not a hash-like object." unless auto_vivifiy_on_read
+ raise ArgumentError, "You tried to set a nested key, where the parent is not a hash-like object: #{@state.join("/")}/#{key} " unless auto_vivifiy_on_read
end
else
data_hash[key] = Mash.new