From adaed1ebcb4af2a7203d61e70b826f69f880fb2f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 2 Apr 2008 11:45:03 +0000 Subject: Adding Hash#without Closes #7369 [eventualbuddha] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9209 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activesupport/CHANGELOG | 2 ++ .../lib/active_support/core_ext/hash/slice.rb | 16 +++++++++++ activesupport/test/core_ext/hash_ext_test.rb | 32 ++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 307cc7f405..78978ac981 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Adding Hash#without Closes #7369 [eventualbuddha] + * TimeWithZone#method_missing: send to utc to advance with dst correctness, otherwise send to time. Adding tests for time calculations methods [Geoff Buesing] * Add config.active_support.use_standard_json_time_format setting so that Times and Dates export to ISO 8601 dates. [rick] diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb index 6fe5e05330..c270e3906b 100644 --- a/activesupport/lib/active_support/core_ext/hash/slice.rb +++ b/activesupport/lib/active_support/core_ext/hash/slice.rb @@ -11,6 +11,11 @@ module ActiveSupport #:nodoc: # end # # search(options.slice(:mass, :velocity, :time)) + # + # Also allows leaving out certain keys. This is useful when duplicating + # a hash but omitting a certain subset: + # + # Event.new(event.attributes.without(:id, :user_id)) module Slice # Returns a new hash with only the given keys. def slice(*keys) @@ -22,6 +27,17 @@ module ActiveSupport #:nodoc: def slice!(*keys) replace(slice(*keys)) end + + # Returns a new hash without the given keys. + def without(*keys) + allowed = self.keys - (respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys) + slice(*allowed) + end + + # Replaces the hash without the given keys. + def without!(*keys) + replace(without(*keys)) + 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 706e218abc..9d1d6ec33f 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -310,6 +310,38 @@ class HashExtTest < Test::Unit::TestCase assert_equal expected, original.except!(:c) assert_equal expected, original end + + def test_without + original = { :a => 'x', :b => 'y', :c => 10 } + expected = { :a => 'x' } + + # Should return a hash without the given keys. + assert_equal expected, original.without(:b, :c) + assert_not_equal expected, original + + # Should ignore non-existant keys. + assert_equal expected, original.without(:b, :c, :d) + + # Should replace the hash with the given keys taken away. + assert_equal expected, original.without!(:b, :c) + assert_equal expected, original + end + + def test_indifferent_without + original = { :a => 'x', :b => 'y', :c => 10 }.with_indifferent_access + expected = { :c => 10 }.with_indifferent_access + + [['a', 'b'], [:a, :b]].each do |keys| + # Should return a new hash without the given keys. + assert_equal expected, original.without(*keys), keys.inspect + assert_not_equal expected, original + + # Should replace the hash without the given keys. + copy = original.dup + assert_equal expected, copy.without!(*keys) + assert_equal expected, copy + end + end end class IWriteMyOwnXML -- cgit v1.2.3