繁体   English   中英

列出所有Ruby类和方法

[英]List all Ruby classes and methods

一段时间以来,我一直希望有一种方法可以在加载特定模型时检查对给定红宝石环境所做的所有更改。 此外,具有比较和对比在不同版本的ruby和不同的Ruby VM中可用的方法和类的能力。

我创建了一些使用元编程生成这样的列表的代码:

arr = []
arr << "Ruby version " + ::RUBY_VERSION
arr << ""
Module.constants.each do |const|
  if ::Module.const_defined? const
    #If for whatever reason const_get fails, then rescue.
    begin
      obj = Module.const_get(const)
      if obj
        if obj.is_a? Class
        # Class methods
        arr << (obj.singleton_methods).sort.map do |method_sym|
          obj.to_s + "::" + method_sym.to_s
        end

        # Instance methods
        arr << (obj.instance_methods - (obj.superclass ? obj.superclass.instance_methods : []) - Object.methods).sort.map do |method_sym|
          "#<" + obj.to_s + ">." + method_sym.to_s
        end
        elsif obj.is_a? Module
          arr << (obj.methods - Module.methods).sort.map do |method_sym|
            obj.to_s + "::" + method_sym.to_s
          end
        else
          # Methods
          arr << "::" + const.to_s
        end
      end
    rescue
    end
  end
end

File.new("D:\\methods_#{::RUBY_VERSION}.txt","w").write(arr.flatten.sort.join("\n"))

该列表的标准是它应列出所有非继承的实例和类方法。 常量用::前缀表示,类方法表示为MyClass::someMethod ,实例方法表示为: #<MyClass>.someMethod

上面的脚本大部分都起作用,但是错过了ObjectBasicObject IE在创建的列表中没有以#<Object>.为前缀的行#<Object>. Object:: 我是否缺少明显的东西?

我建议您为每个Ruby版本创建一个哈希,然后将该哈希或其内容保存到名称指示Ruby版本的文件中(例如, v_2-5-1.jsonv_2-5-1.txt

虽然我不完全理解这个问题,但是您可以在这里找到ObjectSpace :: each_object方法。 例如,

h = ObjectSpace.each_object(Class).with_object({}) do |c,h|
  h[c] = { cm: c.methods(false).sort, im: c.instance_methods(false).sort,
           con: c.constants.sort }
end

h.keys && [Object, BasicObject]
  # [Object, BasicObject]

如您所见, ObjectBasicObject是此哈希中的两个键(类)。 让我们看一下其中一个键的值: Dir

h[Dir]
  #=> {:cm=>[:[], :chdir, :children, :chroot, :delete, :each_child, :empty?,
  #          :entries, :exist?, :exists?, :foreach, :getwd, :glob, :home,
  #          :mkdir, :open, :pwd, :rmdir, :unlink],
  #    :im=>[:close, :each, :fileno, :inspect, :path, :pos, :pos=, :read,
  #          :rewind, :seek, :tell, :to_path],
  #    :con=>[]}

这是为了

RUBY_VERSION
  #=> "2.5.1"

将此哈希的内容与Dir for v2.5.1的文档进行比较,我们发现结果对于Dir类是正确的。

获取在类C定义的常量是有问题的。 我上面使用的C.constants包括继承的常量。 我是在写C.constants - C.superclass.constants (注意BasicObject.superclass #=> nil ),它不会在C重新定义继承的常量(并且重新定义继承的常量不会产生警告消息)。

您可能希望检查所有模块( ObjectSpace.each_object(Module) ),然后将一个键值:is_class添加到具有truefalse值的哈希中,而不仅仅是查看类:

您可能希望将其他键添加到哈希中。 :superclass:included_modules (对于classes)是我想到的两个。 :nesting (对于非类模块)是另一个。 参见Module :: nesting 我怀疑这些发现只是表面上的,两个Ruby版本的有意义的比较会非常复杂。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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