Skip to content

Commit

Permalink
Fix AS::HWIA#select and #reject on Ruby 2.1.1+
Browse files Browse the repository at this point in the history
In Ruby 2.1.1 and later select and reject return a new instance of
Hash rather than the subclass so we need to override them to return
an instance of the correct class.
  • Loading branch information
pixeltrix committed Nov 2, 2016
1 parent 2118627 commit 03e3aed
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
14 changes: 14 additions & 0 deletions activesupport/lib/active_support/hash_with_indifferent_access.rb
Expand Up @@ -153,6 +153,20 @@ def stringify_keys; dup end
def symbolize_keys; to_hash.symbolize_keys end
def to_options!; self end

if RUBY_VERSION > '2.1.0'
# On Ruby 2.1.1 and later the behavior of .select and reject changed to
# return a new Hash instance so we need to override them to return an
# instance of the correct class.

def select(*args, &block)
dup.tap { |hash| hash.select!(*args, &block) }
end

def reject(*args, &block)
dup.tap { |hash| hash.reject!(*args, &block) }
end
end

# Convert to a Hash with String keys.
def to_hash
Hash.new(default).merge!(self)
Expand Down
30 changes: 30 additions & 0 deletions activesupport/test/core_ext/hash_ext_test.rb
Expand Up @@ -259,6 +259,36 @@ def test_indifferent_deleting
assert_equal hash.delete('a'), nil
end

def test_indifferent_select
hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).select { |k, v| v == 1 }

assert_equal({ "a" => 1 }, hash)
assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash
end

def test_indifferent_select_bang
indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings)
indifferent_strings.select! { |k, v| v == 1 }

assert_equal({ "a" => 1 }, indifferent_strings)
assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings
end

def test_indifferent_reject
hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).reject { |k, v| v != 1 }

assert_equal({ "a" => 1 }, hash)
assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash
end

def test_indifferent_reject_bang
indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings)
indifferent_strings.reject! { |k, v| v != 1 }

assert_equal({ "a" => 1 }, indifferent_strings)
assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings
end

def test_indifferent_to_hash
# Should convert to a Hash with String keys.
assert_equal @strings, @mixed.with_indifferent_access.to_hash
Expand Down

0 comments on commit 03e3aed

Please sign in to comment.