diff --git a/lib/key_path/enumerable/extensions.rb b/lib/key_path/enumerable/extensions.rb index 3d792dd..f2d3054 100644 --- a/lib/key_path/enumerable/extensions.rb +++ b/lib/key_path/enumerable/extensions.rb @@ -23,29 +23,32 @@ def set_keypath(keypath, value) # handle both string and KeyPath::Path forms keypath = keypath.to_keypath if keypath.is_a?(String) - # create a collection at the keypath - collection = keypath.to_collection - - # set the value in the collection - depth = '' - keypath.to_a.each do |e| - # walk down set and make up the right place to assign - if e.is_number? - key = "#{e}" - else - key = ":#{e}" - end - depth << "[#{key}]" + keypath_parts = keypath.to_a + # Return self if path empty + return self if keypath_parts.empty? + + key = keypath_parts.shift + # Just assign value to self when it's a direct path + # Remember, this is after calling keypath_parts#shift + if keypath_parts.length == 0 + key = key.is_number? ? Integer(key) : key.to_sym + + self[key] = value + return self end - # assign it - if value.is_a? String - eval "collection#{depth} = '#{value}'" + # keypath_parts.length > 0 + # Remember, this is after calling keypath_parts#shift + collection = if key.is_number? + Array.new else - eval "collection#{depth} = #{value}" + Hash.new end + # Remember, this is after calling keypath_parts#shift + collection.set_keypath(keypath_parts.join('.'), value) + # merge the new collection into self - self.deep_merge!(collection) + self[key] = collection end end diff --git a/lib/key_path/path.rb b/lib/key_path/path.rb index 3d2c9ad..6da1c55 100644 --- a/lib/key_path/path.rb +++ b/lib/key_path/path.rb @@ -24,31 +24,6 @@ def to_a @path.split('.') end - def to_collection - collection = {} - s = to_a - depth = '' - - s.each do |e| - # assemble the key - if e.is_number? - key = "#{e}" - else - key = ":#{e}" - end - depth << "[#{key}]" - - # figure out the correct type to push - type = {} - type = [] if e.is_plural? - - # evaluate this stage - eval "collection#{depth} = #{type}" - end - - collection - end - def inspect "#<#{self.class.name}:#{object_id} path=#{@path}>" end diff --git a/spec/path_spec.rb b/spec/path_spec.rb index 7eff844..2a18260 100644 --- a/spec/path_spec.rb +++ b/spec/path_spec.rb @@ -37,30 +37,3 @@ path.parent.must_be_nil end end - -describe 'KeyPath::Path collections generation' do - it 'returns an empty hash with an empty path' do - path = KeyPath::Path.new('') - path.to_collection.must_equal({}) - end - - it 'returns a nested hash for a single path unit' do - path = KeyPath::Path.new('item') - path.to_collection.must_equal(item: {}) - end - - it 'returns a nested array when the key is plural' do - path = KeyPath::Path.new('items') - path.to_collection.must_equal(items: []) - end - - it 'returns a double nested array with a two set keypath' do - path = KeyPath::Path.new('item.id') - path.to_collection.must_equal(item: { id: {} }) - end - - it 'returns a nested array with an item' do - path = KeyPath::Path.new('items.0.id') - path.to_collection.must_equal(items: [{ id: {} }]) - end -end