This project is archived and is in readonly mode.

#2884 ✓invalid
Jérémy Lecour

reverse_merge!() modifies the hash outside the method scope

Reported by Jérémy Lecour | July 8th, 2009 @ 01:51 PM | in 2.x

Hi,

I have a Hash that is passed as a method argument to several methods on different Models. It has to be the same when it enters each method, but each Model can apply some specific default values to the Hash with reverse_merge!()

I'm surprised to see that in fact each method call modifies the original Hash, the one that is outside the scope of each method.

I don't doubt that it's an absolutly normal behavior from a Ruby perspective, but I don't think it's normal from the Rails perspective. At least I didn't expect this.

I've written a small rake task to illustrate this :

desc "bug reverse_merge!"
task(:reverse_merge) do
  
  options = {
    :attr1 => "generic string"
  }
  
  def some_method(options = {})
    default_options = {
      :attr1 => "default string",
      :attr2 => "another string"
    }
    options.reverse_merge!(default_options)

    puts "*** options INSIDE the method call :"
    puts options.inspect
  end
  
  puts "*** options BEFORE the method call :"
  puts options.inspect
  
  some_method(options)
  
  puts "*** options AFTER the method call :"
  puts options.inspect
  
end

Comments and changes to this ticket

  • Mike Breen

    Mike Breen April 24th, 2010 @ 06:54 PM

    • Assigned user set to “Ryan Bigg”

    Ruby passes params by reference not by value so I'm not sure why we would expect Rails to behave differently.

    What you probably want to do here is to use the non-bang version.

    def some_method(options = {})
      default_options = {
        :attr1 => "default string",
        :attr2 => "another string"
      }
      my_options = options.reverse_merge(default_options)
    
      puts "*** options INSIDE the method call :"
      puts my_options.inspect
    end
    
  • Ryan Bigg

    Ryan Bigg April 25th, 2010 @ 12:14 AM

    • State changed from “new” to “invalid”

    I agree with Mike here.

  • Jérémy Lecour

    Jérémy Lecour April 25th, 2010 @ 10:11 PM

    I also agree with Mike. I guess I misinterpreted something. Sorry about that.

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