This project is archived and is in readonly mode.

#3299 ✓stale
David James

HashWithIndifferentAccess#merge should accept block just like Hash#merge

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

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.

Comments and changes to this ticket

  • David James

    David James September 28th, 2009 @ 07:08 PM

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

  • David James

    David James September 28th, 2009 @ 07:09 PM

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

  • Álvaro Bautista

    Álvaro Bautista November 29th, 2009 @ 08:07 PM

    • Tag changed from activesupport, hashwithindifferentaccess to activesupport, hashwithindifferentaccess, patch

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

  • Eric

    Eric June 29th, 2010 @ 05:05 AM

    • Importance changed from “” to “”

    Is this going to be merged?

  • Neeraj Singh

    Neeraj Singh June 29th, 2010 @ 05:45 AM

    • State changed from “new” to “open”

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

    The patch looks good.

  • Bruno Michel
  • José Valim

    José Valim June 30th, 2010 @ 03:59 PM

    • Assigned user set to “Xavier Noria”
  • Álvaro Bautista

    Álvaro Bautista June 30th, 2010 @ 04:24 PM

    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).

  • Xavier Noria

    Xavier Noria October 30th, 2010 @ 10:53 PM

    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?

  • Álvaro Bautista

    Álvaro Bautista October 31st, 2010 @ 10:18 AM

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

  • Jeff Kreeftmeijer

    Jeff Kreeftmeijer November 8th, 2010 @ 08:54 AM

    • Tag cleared.

    Automatic cleanup of spam.

  • Santiago Pastorino

    Santiago Pastorino February 9th, 2011 @ 12:31 AM

    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.

  • Santiago Pastorino

    Santiago Pastorino February 9th, 2011 @ 12:31 AM

    • State changed from “open” to “stale”
  • Lyle Underwood

    Lyle Underwood March 23rd, 2011 @ 06:30 PM

    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"}
    

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages