Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Hash with indifferent access reverse merge problem

#421

My business partner Rodney ran into this isse the other day.

http://blog.internautdesign.com/...

I think it is a bug, that violates the Principle of Least Surprise.

Loading development environment (Rails 2.1.0)
>> z = HashWithIndifferentAccess.new
=> {}
>> z.reverse_merge!( :a => 1 )
=> {:a=>1}
>> z.reverse_merge!( 'a' => 1 )
=> {"a"=>1, :a=>1}

Reverse merging on a HashWithIndifferentAccess should return a new HashWithIndifferentAccess, not a normal hash.

The solution is to overload HashWithIndifferentAccess#reverse_merge:

>> class HashWithIndifferentAccess
>>   def reverse_merge(other_hash)
>>     self.class.new( other_hash.merge(self) )
>>   end
>> end
=> nil
>> z = HashWithIndifferentAccess.new
=> {}
>> z.reverse_merge!( :a => 1 )
=> {"a"=>1}
>> z.reverse_merge!( 'a' => 1 )
=> {"a"=>1}
>> 

I'm attaching a patch with a test.

Reported by David Lowenfels · June 15th, 2008 @ 06:23 AM

State: resolved
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. DrMark
    DrMark
    • Tag set to activesupport, bug, core_ext, patch

    +1 This is rather unexpected behavior. Given that Ruby tries to do the least surprising thing, shouldn't we fix this?

    June 26th, 2008 @ 03:14 AM

  2. Rodney Carvalho
    Rodney Carvalho

    +1 Yes, this caused me hours of frustration. Indifferent access should happen on both getting and setting.

    July 8th, 2008 @ 11:46 PM

  3. Gregory Tomei
    Gregory Tomei

    this does seem to be inconsistent with how the HashWithIndifferentAccess class is intended to work.

    July 23rd, 2008 @ 03:04 AM

  4. H@rlan Knight
    H@rlan Knight

    +1 Agreed, this would be a serious improvement. The current behavior leads to difficult-to-trace bugs.

    July 23rd, 2008 @ 05:53 AM

  5. Noah Thorp
  6. Brad Folkens
    Brad Folkens

    +1 Just ran into this problem this morning with some failing tests - unexpected behavior

    October 27th, 2008 @ 03:10 PM

  7. Brad Folkens
    Brad Folkens
    • Tag changed from activesupport, bug, core_ext, patch to activesupport, bug, core_ext, patch, verified

    I have a slightly different take on this now, some of my tests on my app started failing with the previous patch.

    This updated version seems to work for additional cases but for some reason I can't get the activesupport tests to break (proving this update works). The problem seems to occur in the full rails stack when it is more than just the simple case being merged.

    Solution is to convert the hash passed into reverse_merge into HashWithIndifferentAccess first, then merge.

    January 9th, 2009 @ 04:23 PM

  8. Dmitry Ratnikov
    Dmitry Ratnikov

    I have modified the second patch a bit further by re-using the underlying implementation of reverse_merge rather than dublicating it again.

    January 16th, 2009 @ 08:36 PM

  9. Repository
    Repository
    • State changed from new to resolved

    (from [aa57e66fec3a131f5d246b8950a2c3286f858b78]) Ensure HWIA#reverse_merge! retrurns HWIA [#421 state:resolved]

    Signed-off-by: Pratik Naik pratiknaik@gmail.com http://github.com/rails/rails/co...

    March 12th, 2009 @ 03:14 PM