Skip to content

Undefine original method in InstanceMethodStasher#stash

gitlab-qa-bot requested to merge handle-method-redefinition-warning into master

Created by: yujinakayama

... to handle the method redefinition warning on MRI 2.3:

/Users/me/Projects/rspec-dev/repos/rspec-mocks/lib/rspec/mocks/method_double.rb:63: warning: method redefined; discarding old running_in_drb?
/Users/me/Projects/rspec-dev/repos/rspec-core/lib/rspec/core/runner.rb:150: warning: previous definition of running_in_drb? was here

For some reason MRI 2.2 does not warn of method redefinition when the original method handle has been taken with Object#method before the redefinition. On the other hand, MRI 2.3 warns of it regardless of whether the original method handle has been taken or not.

obj = Object.new

def obj.foo
  :original_foo
end

obj.method(:foo) if ARGV.first == 'take_method_handle'

singleton_klass = class << obj; self; end
singleton_klass.class_exec do
  define_method(:foo) { }
end
$ ruby -v -w test.rb
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin14]
test.rb:11: warning: method redefined; discarding old foo
test.rb:3: warning: previous definition of foo was here

$ ruby -v -w test.rb take_method_handle
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin14]

$ ruby -v -w test.rb
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin14]
test.rb:11: warning: method redefined; discarding old foo
test.rb:3: warning: previous definition of foo was here

$ ruby -v -w test.rb take_method_handle
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin14]
test.rb:11: warning: method redefined; discarding old foo
test.rb:3: warning: previous definition of foo was here

Previously we have left the original method as is in InstanceMethodStasher#stash, because it would soon be overwritten in MethodDouble#define_proxy_method. However now MRI 2.3 warns of it, so we should properly undefine the original method before redefining it.

@rspec/rspec Thoughts?

This fixes #1041 (closed).

Merge request reports