Project

General

Profile

Bug #12206

undef_method on prepended module undefines same-name method on prepending class

Added by EugeneG (Eugene Gilburg) about 1 year ago. Updated 12 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin12.0]
[ruby-core:74491]

Description

  1. Define a class with a method
  2. Define a module with a same-name method
  3. Prepend the module on the class
  4. Undefine the same-name method on the module, not touching the original method on the class
  5. Observe the class method to also become undefined
class MyClass
  def foo
    "MyClass#foo"
  end
end

module MyMod
  def foo
    "#{super} prepended by MyMod#foo"
  end
end

MyClass.prepend(MyMod)

MyClass.new.foo
# => "MyClass#foo prepended by MyMod#foo"

MyClass.instance_method(:foo) == MyMod.instance_method(:foo)
# => false

MyMod.send(:undef_method, :foo)

# The bug:

MyClass.new.foo
# => NoMethodError: undefined method `foo' for #<MyClass:0x007ffdf29614a8>

Expected behavior: MyClass#foo would still return "MyClass#foo" since I only undefined foo on the module, not on the class.

Real life use case: I'm setting up instrumentation code that can track and measure/benchmark call times of specific methods, but after it's done I want to clean up and restore original code the way it was. For me, it would be even better to support to "unprepend" a module from a class instead of undef_method on the mod, but that's more of a feature request than a bug).

History

#1 [ruby-core:74495] Updated by znz (Kazuhiro NISHIYAMA) 12 months ago

How about using remove_method instead of undef_method ?

#2 [ruby-core:74497] Updated by EugeneG (Eugene Gilburg) 12 months ago

Kazuhiro NISHIYAMA wrote:

How about using remove_method instead of undef_method ?

It worked, thanks! Behavior is still confusing since I undef'd the method on the module rather than the class, but this solves my problem.

Also available in: Atom PDF