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

如何获得Ruby类中未定义方法的列表?,ruby,reflection,Ruby,Reflection,在使用Ruby时,我编写了以下代码: A类 终止 A.singleton\u class.instance\u eval do undef_方法:新 终止 #或 #类NoMethodError:A:class的未定义方法“new” >来自(irb):8 >from/home/mmsequeira/.rvm/rubies/ruby-1.9.3-p327/bin/irb:16:in`' 这很酷。但是我怎么知道在给定的类中哪些方法是未定义的呢?也许你需要重新定义模块#未定义的方法 class Mod

在使用Ruby时,我编写了以下代码:

A类
终止
A.singleton\u class.instance\u eval do
undef_方法:新
终止
#或
#类NoMethodError:A:class的未定义方法“new”
>来自(irb):8
>from/home/mmsequeira/.rvm/rubies/ruby-1.9.3-p327/bin/irb:16:in`'

这很酷。但是我怎么知道在给定的类中哪些方法是未定义的呢?

也许你需要重新定义
模块#未定义的方法

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]]
A类
终止
A.singleton\u class.instance\u eval do
undef_方法:新
终止
Module.undf_方法
#=>

也许您需要重新定义
模块#undef_方法

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]]
A类
终止
A.singleton\u class.instance\u eval do
undef_方法:新
终止
Module.undf_方法
#=>

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

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

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

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

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


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

您不能。你为什么要知道?只是在探索Ruby。Ruby的反射非常好,因此无法获得此信息似乎很奇怪。@allareri我不这么认为。FWIW Ruby确实在内部跟踪未定义的方法(
VM\u METHOD\u TYPE\u unde
——这就是它如何确保将来的调用不会在基类实现上着陆的原因,请参见),但是在查看Ruby源代码时,我没有找到一种检索这些方法列表的方法,而不是编写本机代码。@MMSequeira疏忽可能不是原因;更有可能的是,这种想法可能是,既然你不能用它做任何事情(比如un-
unde
it),那么为什么你需要知道它的存在呢?换句话说,如果它不再嘎嘎作响,你真的需要知道它曾经是一只鸭子吗?你不能。你为什么要知道?只是在探索Ruby。Ruby的反射非常好,因此无法获得此信息似乎很奇怪。@allareri我不这么认为。FWIW Ruby确实在内部跟踪未定义的方法(
VM\u METHOD\u TYPE\u unde
——这就是它如何确保将来的调用不会在基类实现上着陆的原因,请参见),但是在查看Ruby源代码时,我没有找到一种检索这些方法列表的方法,而不是编写本机代码。@MMSequeira疏忽可能不是原因;更有可能的是,这种想法可能是,既然你不能用它做任何事情(比如un-
unde
it),那么为什么你需要知道它的存在呢?换句话说,如果它不再嘎嘎作响,你真的需要知道它曾经是一只鸭子吗?这不会捕获用
undef
关键字而不是
undef\u method
方法定义的方法。没错。我以为这就是我要问的。如果OP还想捕获
undef
,那么它可以很容易地扩展。实际上,
undef
是一个关键字,因此在不更改Ruby源代码并重新编译的情况下无法覆盖它。好主意。但是,我只会在别名后得到未定义的方法。@MMSequeira这应该无关紧要,除非您试图取消定义
undef_方法
,在这种情况下,它将是一团混乱。这不会捕获使用
undef
关键字而不是
undef_方法
方法未定义的方法。没错。我以为这就是我要问的。如果OP还想捕获
undef
,那么它可以很容易地扩展。实际上,
undef
是一个关键字,因此在不更改Ruby源代码并重新编译的情况下无法覆盖它。好主意。但是,我只会在使用别名后将方法取消定义。@MMSequeira这不重要,除非您试图取消定义
undef_method
,在这种情况下,它会变得一团糟。这比我的方法漂亮得多,而且具有通用性。@sawa感谢
:)
。我花了一段时间才意识到未定义的方法是一件事。谢谢,@AndrewMarshall!非常有帮助!完成。再次感谢,@AndrewMarshall!这比我的漂亮多了,而且有普遍性。@sawa谢谢
:)
。我花了一段时间才意识到未定义的方法是一件事。谢谢,@AndrewMarshall!非常有帮助!完成。再次感谢,@AndrewMarshall!