diff options
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/CHANGELOG | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash.rb | 9 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash/slice.rb | 28 | ||||
-rw-r--r-- | activesupport/test/core_ext/hash_ext_test.rb | 29 |
4 files changed, 63 insertions, 5 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 9f5c98a1cd..a97cba31ee 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Hash#slice(*keys) returns a new hash with only the given keys. #slice! replaces the hash with only the given keys. Works with HashWithIndifferentAccess also. [Jeremy Kemper] + * HashWithIndifferentAccess#to_hash converts to a Hash with String keys and the same default value. [Jeremy Kemper] * Fix remove_constant to correctly handle constant names of the form "::A::...". References #6720. [Nicholas Seckar] diff --git a/activesupport/lib/active_support/core_ext/hash.rb b/activesupport/lib/active_support/core_ext/hash.rb index 7d94d70910..2a99468b4e 100644 --- a/activesupport/lib/active_support/core_ext/hash.rb +++ b/activesupport/lib/active_support/core_ext/hash.rb @@ -1,8 +1,6 @@ -require File.dirname(__FILE__) + '/hash/keys' -require File.dirname(__FILE__) + '/hash/indifferent_access' -require File.dirname(__FILE__) + '/hash/reverse_merge' -require File.dirname(__FILE__) + '/hash/conversions' -require File.dirname(__FILE__) + '/hash/diff' +%w(keys indifferent_access reverse_merge conversions diff slice).each do |ext| + require "#{File.dirname(__FILE__)}/hash/#{ext}" +end class Hash #:nodoc: include ActiveSupport::CoreExtensions::Hash::Keys @@ -10,4 +8,5 @@ class Hash #:nodoc: include ActiveSupport::CoreExtensions::Hash::ReverseMerge include ActiveSupport::CoreExtensions::Hash::Conversions include ActiveSupport::CoreExtensions::Hash::Diff + include ActiveSupport::CoreExtensions::Hash::Slice end diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb new file mode 100644 index 0000000000..6fe5e05330 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/hash/slice.rb @@ -0,0 +1,28 @@ +require 'set' + +module ActiveSupport #:nodoc: + module CoreExtensions #:nodoc: + module Hash #:nodoc: + # Slice a hash to include only the given keys. This is useful for + # limiting an options hash to valid keys before passing to a method: + # + # def search(criteria = {}) + # assert_valid_keys(:mass, :velocity, :time) + # end + # + # search(options.slice(:mass, :velocity, :time)) + module Slice + # Returns a new hash with only the given keys. + def slice(*keys) + allowed = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys) + reject { |key,| !allowed.include?(key) } + end + + # Replaces the hash with only the given keys. + def slice!(*keys) + replace(slice(*keys)) + end + end + end + end +end diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index 8e20f15518..90468fd5a9 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -243,6 +243,35 @@ class HashExtTest < Test::Unit::TestCase def test_diff assert_equal({ :a => 2 }, { :a => 2, :b => 5 }.diff({ :a => 1, :b => 5 })) end + + def test_slice + original = { :a => 'x', :b => 'y', :c => 10 } + expected = { :a => 'x', :b => 'y' } + + # Should return a new hash with only the given keys. + assert_equal expected, original.slice(:a, :b) + assert_not_equal expected, original + + # Should replace the hash with only the given keys. + assert_equal expected, original.slice!(:a, :b) + assert_equal expected, original + end + + def test_indifferent_slice + original = { :a => 'x', :b => 'y', :c => 10 }.with_indifferent_access + expected = { :a => 'x', :b => 'y' }.with_indifferent_access + + [['a', 'b'], [:a, :b]].each do |keys| + # Should return a new hash with only the given keys. + assert_equal expected, original.slice(*keys), keys.inspect + assert_not_equal expected, original + + # Should replace the hash with only the given keys. + copy = original.dup + assert_equal expected, copy.slice!(*keys) + assert_equal expected, copy + end + end end class IWriteMyOwnXML |