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.

HashWithIndifferentAccess#merge should accept block just like Hash#merge

#3299

I would like to see ActiveSupport support the block form of merge.

  # from http://ruby-doc.org/core/classes/Hash.html#M002879
  hsh.merge(other_hash) do |key, old_val, new_val|
    # ...
  end

This form of #merge comes in handy when you have duplicate keys that need to be resolved, such as in the case of two-level merges or recursive merges.

Reported by David James · September 28th, 2009 @ 07:04 PM

State: stale
Milestone: none
Assigned to: Xavier Noria Xavier Noria
Importance: none

Activity

  1. David James
    David James

    I forgot to mention that HashWithIndifferentAccess 'covers up' the underlying Hash#merge, making it hard to get to the original behavior.

    September 28th, 2009 @ 07:08 PM

  2. David James
    David James

    My workaround for now will be to using #to_hash to convert to a normal hash. Then I can use Hash#merge.

    September 28th, 2009 @ 07:09 PM

  3. Álvaro Bautista
    Álvaro Bautista
    • Tag changed from activesupport, hashwithindifferentaccess to activesupport, hashwithindifferentaccess, patch

    That behaviour could be easily implemented. I wrote a simple patch which provides it.

    November 29th, 2009 @ 08:07 PM

  4. Eric
    Eric
    • Importance changed from to

    Is this going to be merged?

    June 29th, 2010 @ 05:05 AM

  5. Neeraj Singh
    Neeraj Singh
    • State changed from new to open

    @Alvaro could you please supply a patch for rails3 too?

    The patch looks good.

    June 29th, 2010 @ 05:45 AM

  6. Bruno Michel
  7. José Valim
    José Valim
    • Assigned user set to Xavier Noria

    June 30th, 2010 @ 03:59 PM

  8. Álvaro Bautista
    Álvaro Bautista

    Hi

    Sorry I haven't had time to update the patch.

    It seems that my slight modification works in Rails 3, however it needs to be into another file (as Bruno's patch shows).

    June 30th, 2010 @ 04:24 PM

  9. Xavier Noria
    Xavier Noria

    There's a fine point about Hash#merge with block: the block is called only for existing keys in the receiver.

    For example, if you execute

    h = {:a => 0}
    g = {:a => 1, :b => 2}
    
    h.merge(g) do |key, oldval, newval|
      p key
    end
    

    you'll see only :a is printed.

    Could you please revise the patch taking that into account?

    October 30th, 2010 @ 10:53 PM

  10. Álvaro Bautista
    Álvaro Bautista

    You're right, I didn't take that into account. Here it is a patch that does.

    October 31st, 2010 @ 10:18 AM

  11. Jeff Kreeftmeijer
    Jeff Kreeftmeijer
    • Tag cleared.

    Automatic cleanup of spam.

    November 8th, 2010 @ 08:54 AM

  12. Santiago Pastorino
    Santiago Pastorino

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

    February 9th, 2011 @ 12:31 AM

  13. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 9th, 2011 @ 12:31 AM

  14. Lyle Underwood
    Lyle Underwood

    I'm on Rails 3.0.3 and as far as I can tell the block syntax for ActiveSupport::HashWithIndifferentAccess#merge is not working at all.

    irb(main):023:0> a = {"one"=>"aye", "two"=>"bee"}
    => {"one"=>"aye", "two"=>"bee"}
    irb(main):024:0> a.merge(a) {|k,v| 1}
    => {"one"=>1, "two"=>1}
    
    irb(main):025:0> b = ActiveSupport::HashWithIndifferentAccess.new("one"=>"aye", "two"=>"bee")
    => {"one"=>"aye", "two"=>"bee"}
    irb(main):026:0> b.merge(b) {|k,v| 1}
    => {"one"=>"aye", "two"=>"bee"}
    

    March 23rd, 2011 @ 06:30 PM