This project is archived and is in readonly mode.
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 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
-
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>