diff --git a/lib/sinatra/indifferent_hash.rb b/lib/sinatra/indifferent_hash.rb index 08126bba..9d54e317 100644 --- a/lib/sinatra/indifferent_hash.rb +++ b/lib/sinatra/indifferent_hash.rb @@ -146,6 +146,17 @@ module Sinatra super(other_hash.is_a?(self.class) ? other_hash : self.class[other_hash]) end + if method_defined?(:transform_values!) # Added in Ruby 2.4 + def transform_values(&block) + dup.transform_values!(&block) + end + + def transform_values! + super + super(&method(:convert_value)) + end + end + private def convert_key(key) diff --git a/test/indifferent_hash_test.rb b/test/indifferent_hash_test.rb index 69101b48..2ceb65d5 100644 --- a/test/indifferent_hash_test.rb +++ b/test/indifferent_hash_test.rb @@ -205,4 +205,22 @@ class TestIndifferentHash < Minitest::Test @hash.replace(?a=>1, :q=>2) assert_equal({ ?a=>1, ?q=>2 }, @hash) end + + def test_transform_values! + skip_if_lacking :transform_values! + + @hash.transform_values! { |v| v.is_a?(Hash) ? Hash[v.to_a] : v } + + assert_instance_of Sinatra::IndifferentHash, @hash[:simple_nested] + end + + def test_transform_values + skip_if_lacking :transform_values + + hash2 = @hash.transform_values { |v| v.respond_to?(:upcase) ? v.upcase : v } + + refute_equal @hash, hash2 + assert_equal :A, hash2[:a] + assert_equal :A, hash2[?a] + end end