Permalink
Browse files

Dup keys in OrderedHash to prevent them from being modified [#1676 st…

…ate:resolved]

Signed-off-by: Frederick Cheung <frederick.cheung@gmail.com>
  • Loading branch information...
1 parent 5ed119c commit 452cd74d81ecfa38d0c7d3a4dc83d2b731de9e73 @bkeepers bkeepers committed with lifo Jan 4, 2009
Showing with 31 additions and 10 deletions.
  1. +22 −9 activesupport/lib/active_support/ordered_hash.rb
  2. +9 −1 activesupport/test/ordered_hash_test.rb
@@ -10,10 +10,14 @@ def initialize(*args, &block)
@keys = []
end
+ def initialize_copy(other)
+ super
+ # make a deep copy of keys
+ @keys = other.keys
+ end
+
def []=(key, value)
- if !has_key?(key)
- @keys << key
- end
+ @keys << key if !has_key?(key)
super
end
@@ -24,6 +28,12 @@ def delete(key)
end
super
end
+
+ def delete_if
+ super
+ sync_keys!
+ self
+ end
def reject!
super
@@ -36,7 +46,7 @@ def reject(&block)
end
def keys
- @keys
+ @keys.dup
end
def values
@@ -56,7 +66,7 @@ def each_value
end
def each
- keys.each {|key| yield [key, self[key]]}
+ @keys.each {|key| yield [key, self[key]]}
end
alias_method :each_pair, :each
@@ -73,13 +83,16 @@ def shift
[k, v]
end
+ def merge!(other_hash)
+ other_hash.each {|k,v| self[k] = v }
+ self
+ end
+
def merge(other_hash)
- result = dup
- other_hash.each {|k,v| result[k]=v}
- result
+ dup.merge!(other_hash)
end
- private
+ private
def sync_keys!
@keys.delete_if {|k| !has_key?(k)}
@@ -98,7 +98,8 @@ def test_each_pair
end
def test_delete_if
- (copy = @ordered_hash.dup).delete('pink')
+ copy = @ordered_hash.dup
+ copy.delete('pink')
assert_equal copy, @ordered_hash.delete_if { |k, _| k == 'pink' }
assert !@ordered_hash.keys.include?('pink')
end
@@ -115,6 +116,7 @@ def test_reject
new_ordered_hash = @ordered_hash.reject { |k, _| k == 'pink' }
assert_equal copy, @ordered_hash
assert !new_ordered_hash.keys.include?('pink')
+ assert @ordered_hash.keys.include?('pink')
end
def test_clear
@@ -140,4 +142,10 @@ def test_shift
assert_equal [@keys.first, @values.first], pair
assert !@ordered_hash.keys.include?(pair.first)
end
+
+ def test_keys
+ original = @ordered_hash.keys.dup
+ @ordered_hash.keys.pop
+ assert_equal original, @ordered_hash.keys
+ end
end

0 comments on commit 452cd74

Please sign in to comment.