Permalink
Browse files

Merge pull request #52 from Erol/deep-key-conversions

Do deep key conversions for nested hashes and arrays.
  • Loading branch information...
2 parents cc8730f + 89007bd commit 7d9cf01d2e31e1789cb890a21c4800b2163857b4 @jch jch committed Jun 23, 2012
Showing with 78 additions and 4 deletions.
  1. +39 −1 lib/hashie/extensions/key_conversion.rb
  2. +39 −3 spec/hashie/extensions/key_conversion_spec.rb
@@ -9,6 +9,7 @@ module StringifyKeys
# test # => {'abc' => 'def'}
def stringify_keys!
keys.each do |k|
+ stringify_keys_recursively!(self[k])
self[k.to_s] = self.delete(k)
end
self
@@ -22,14 +23,15 @@ def stringify_keys
end
module SymbolizeKeys
- # Convert all keys in the hash to strings.
+ # Convert all keys in the hash to symbols.
#
# @example
# test = {'abc' => 'def'}
# test.symbolize_keys!
# test # => {:abc => 'def'}
def symbolize_keys!
keys.each do |k|
+ symbolize_keys_recursively!(self[k])
self[k.to_sym] = self.delete(k)
end
self
@@ -40,6 +42,42 @@ def symbolize_keys!
def symbolize_keys
dup.symbolize_keys!
end
+
+ protected
+
+ # Stringify all keys recursively within nested
+ # hashes and arrays.
+ def stringify_keys_recursively!(object)
+ if self.class === object
+ object.stringify_keys!
+ elsif ::Array === object
+ object.each do |i|
+ stringify_keys_recursively!(i)
+ end
+ object
+ elsif object.respond_to?(:stringify_keys!)
+ object.stringify_keys!
+ else
+ object
+ end
+ end
+
+ # Symbolize all keys recursively within nested
+ # hashes and arrays.
+ def symbolize_keys_recursively!(object)
+ if self.class === object
+ object.symbolize_keys!
+ elsif ::Array === object
+ object.each do |i|
+ symbolize_keys_recursively!(i)
+ end
+ object
+ elsif object.respond_to?(:symbolize_keys!)
+ object.symbolize_keys!
+ else
+ object
+ end
+ end
end
module KeyConversion
@@ -2,7 +2,7 @@
describe Hashie::Extensions::KeyConversion do
subject do
- klass = Class.new(Hash)
+ klass = Class.new(::Hash)
klass.send :include, Hashie::Extensions::KeyConversion
klass
end
@@ -16,6 +16,24 @@
(instance.keys & %w(abc 123)).size.should == 2
end
+ it 'should do deep conversion within nested hashes' do
+ instance[:ab] = subject.new
+ instance[:ab][:cd] = subject.new
+ instance[:ab][:cd][:ef] = 'abcdef'
+ instance.stringify_keys!
+ instance.should == {'ab' => {'cd' => {'ef' => 'abcdef'}}}
+ end
+
+ it 'should do deep conversion within nested arrays' do
+ instance[:ab] = []
+ instance[:ab] << subject.new
+ instance[:ab] << subject.new
+ instance[:ab][0][:cd] = 'abcd'
+ instance[:ab][1][:ef] = 'abef'
+ instance.stringify_keys!
+ instance.should == {'ab' => [{'cd' => 'abcd'}, {'ef' => 'abef'}]}
+ end
+
it 'should return itself' do
instance.stringify_keys!.should == instance
end
@@ -44,13 +62,31 @@
(instance.keys & [:abc, :def]).size.should == 2
end
+ it 'should do deep conversion within nested hashes' do
+ instance['ab'] = subject.new
+ instance['ab']['cd'] = subject.new
+ instance['ab']['cd']['ef'] = 'abcdef'
+ instance.symbolize_keys!
+ instance.should == {:ab => {:cd => {:ef => 'abcdef'}}}
+ end
+
+ it 'should do deep conversion within nested arrays' do
+ instance['ab'] = []
+ instance['ab'] << subject.new
+ instance['ab'] << subject.new
+ instance['ab'][0]['cd'] = 'abcd'
+ instance['ab'][1]['ef'] = 'abef'
+ instance.symbolize_keys!
+ instance.should == {:ab => [{:cd => 'abcd'}, {:ef => 'abef'}]}
+ end
+
it 'should return itself' do
instance.symbolize_keys!.should == instance
end
end
- describe '#stringify_keys' do
- it 'should convert keys to strings' do
+ describe '#symbolize_keys' do
+ it 'should convert keys to symbols' do
instance['abc'] = 'def'
copy = instance.symbolize_keys
copy[:abc].should == 'def'

0 comments on commit 7d9cf01

Please sign in to comment.