如何在Ruby类中获取未定义方法的列表?

时间:2012-11-25 16:27:15

标签: ruby reflection

在玩Ruby的时候,我编写了以下代码:

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>'

这很酷。但是,如何知道在给定的类中哪些方法未定义?

2 个答案:

答案 0 :(得分:3)

默认情况下不能。取消定义方法会将其从存在中删除。但是,您可以在删除它们时记录它们。这可以通过method hooks完成,以捕获所有内容并避免使用丑陋的别名方法链接:

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

这将通过undef_methodundef

捕获未定义的方法
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]

当然,在捕获任何内容之前,必须在Module中包含钩子方法。

答案 1 :(得分:1)

也许您需要重新定义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

然后,你得到:

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