简体   繁体   中英

How can one get the list of undefined methods in a Ruby class?

While playing a bit with Ruby, I wrote the following code:

class A
end

A.singleton_class.instance_eval do
    undef_method :new
end

# or
# class << B
#   undef_method :new
# end

A.new

> NoMethodError: undefined method `new' for A:Class
>         from (irb):8
>         from /home/mmsequeira/.rvm/rubies/ruby-1.9.3-p327/bin/irb:16:in `<main>'

This is cool. But how can I know which methods have been undefined in a given class?

You can't by default. Undefining a method removes it from existence. You could, however, record them as they're removed. This can be done with method hooks to capture everything and avoid ugly alias method chaining:

class Module
  def method_undefined name
    (@undefined_methods ||= []) << name
  end

  def singleton_method_undefined name
    (@undefined_methods ||= []) << name
  end

  def undefined_methods
    @undefined_methods || []
  end
end

This will capture methods undefined via undef_method or undef :

class C
  def foo; end
  def bar; end

  undef foo
  undef_method :bar
end

C.undefined_methods  #=> [:foo, :bar]
C.singleton_class.instance_eval { undef new }
C.singleton_class.undefined_methods  #=> [:new]

Of course, you must include the hook methods in Module before anything can be captured.

Maybe you need to redefine Module#undef_method .

class Module
  alias original_undef_method :undef_method
  @@undef_methods = {}
  def undef_method *methods
    methods.each{|method| @@undef_methods[[self, method]] ||= true}
    original_undef_method(*methods)
  end
  def self.undef_methods; @@undef_methods.keys end
end

Then, you get:

class A
end
A.singleton_class.instance_eval do
    undef_method :new
end
Module.undef_methods
# => [[#<Class:A>, :new]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM