如何列出类的所有方法(不是扩展和包含方法)

Posted

技术标签:

【中文标题】如何列出类的所有方法(不是扩展和包含方法)【英文标题】:How to list all methods of a class (not Extended and Included methods) 【发布时间】:2016-03-25 06:43:13 【问题描述】:

使用 Ruby 2.2.1,如何列出仅在 includeextend 方法被过滤掉的类/文件中定义的类的所有方法(最好是字符串名称数组)。我也想区分类方法和实例方法。

目前,我可以使用 MyClass.methods(false) 获取所有未继承的方法,但这仍然包括属于 include 模块的方法。

明确地说,我有:

class MyClass < BaseClass
  extend AnotherBaseClass
  include MyModule

  def foo
  end

  def bar
  end
end

我想得到:

somecodethatreturnssomething
#=> ['foo', 'bar']
# Not including BaseClass, AnotherBaseClass, and ModuleClass methods

更新:

当我在单独的 irb 控制台中运行@Wand Maker 时,它的答案是正确的。但是,我仍然有一个特别的问题,我在MyClass 中包含ActionView::Helpers::UrlHelper。我总是得到额外的方法:default_url_options?default_url_options=default_url_options。我认为无论是否使用 Rails,include 的行为都是相同的,所以我没有用 Rails 标记这个问题。

我什至在MyClass 的文件末尾添加了byebug,这样我就可以检查类并运行MyClass.singleton_methods(false) 或运行MyClass.instance_methods(false)。但它们仍然包含这三种不需要的方法。

我可以手动从数组中删除这三个额外的方法,这样我就可以获得我的类的动态方法列表,但我只是担心将来如果有更新或添加的东西我的应用程序会中断类的新方法(在不知不觉中)。

更新:

这 3 种方法似乎只添加到 Rails 3 中(我正在处理的项目),但没有添加到 Rails 4 中(正如我和 @Wand Maker 测试的那样)。

这是确切的代码(我已经删除了所有内容,但仍然得到相同的结果/问题)

# lib/my_class.rb
class MyClass
  include ActionView::Helpers::UrlHelper

  def welcome
    puts 'Hello Jules!'
  end

  def farewell
    puts 'Goodbye Jules!'
  end
end

byebug

或者我可以删除该文件:my_class.rb(并将整个代码复制并粘贴到rails console

但是,仍然遇到同样的问题。

【问题讨论】:

仅供参考:如果我使用MyClass &lt; ActionController::Base 并使用MyClass.methods,那么,我看到default_url_options? 和其他方法。如果我使用MyClass.methods(false),我看不到这些方法。你能否分享一下你如何列出方法的确切代码以及你现实生活中MyClass的基类是什么? @WandMaker 我用确切的精简代码更新了问题,我仍然得到这三种方法。 【参考方案1】:

您可以执行以下操作:

MyClass.instance_methods(false)
#=> [:foo, :bar]

如果您想包含MyClass 中定义的任何类方法,您可以这样做:

MyClass.instance_methods(false) + MyClass.singleton_methods(false)

这是定义了所有类/模块的工作示例

class BaseClass
  def moo
  end
end

module AnotherBaseClass
  def boo
  end
end

module MyModule
  def roo
  end
end

class MyClass < BaseClass
  extend AnotherBaseClass
  include MyModule

  def self.goo
  end

  def foo
  end

  def bar
  end
end

p MyClass.instance_methods(false) + MyClass.singleton_methods(false)
#=> [:foo, :bar, :goo]

p RUBY_VERSION
#=> "2.2.2"

【讨论】:

这仍将返回包含模块中定义的方法。 @zwippie 我明白了。我添加了完整的示例,它似乎没有按照您所说的进行。如果我忽略了什么,请告诉我。 pry 中尝试Fixnum.instance_methods(false) @WandMaker 您的(更正的)示例确实返回了正确的方法,但我仍在试图弄清楚这是否总是有效。例如,如果我打开一个 Rails 控制台并尝试MyModel.instance_methods(false)(其中MyModel 是一个ActiveRecord 类),我仍然会得到大量未在MyModel 中直接定义的方法,就像所有before_/after_ 钩子一样。 @WandMaker 确实,在 Rails 之外它可能会返回正确的结果。在 Rails 控制台内部,它会让人发疯:)

以上是关于如何列出类的所有方法(不是扩展和包含方法)的主要内容,如果未能解决你的问题,请参考以下文章

如何列出所有月份名称,例如一个组合?

仅列出 ActiveRecord 子类方法

如何在没有继承方法的情况下获取类的公共方法?

如何在所有类的所有测试之前运行方法?

扩展特征的单元测试类 - 我如何在特征中模拟和存根方法?

PHP:如何防止扩展类的多个实例