Object#with_options behaves surprisingly to me, as it gives the common options priority over the special ones:
with_options(:hello => 'world') do |foo|
foo.p(:hello => 'mars')
# gives: {:hello => "world"}
# should be: {:hello => "mars"}
end
The simple solution is to merge both options the other way round:
- arguments << if arguments.last.respond_to? :merge!
- arguments.pop.dup.merge!(@options)
+ arguments << if arguments.last.respond_to? :to_hash
+ @options.merge(arguments.pop)
(Hash#merge also creates a dup.)
We also need to check if the last argument quacks like a Hash, just having #merge! doesn't suffice.
Performance should be the same in both versions.
I'm not sure if the current behaviour was on purpose; I just ran the tests for ActiveSupport successfully.
Patch with test case attached.