[英]List all Ruby classes and methods
For a while now I've wanted a way to inspect all changes made to a given ruby environment when a particular model is loaded. 一段时间以来,我一直希望有一种方法可以在加载特定模型时检查对给定红宝石环境所做的所有更改。 Furthermore, the ability to compare and contrast the methods and classes available in separate versions of ruby, and different Ruby VMs. 此外,具有比较和对比在不同版本的ruby和不同的Ruby VM中可用的方法和类的能力。
I've created some code which uses meta-programming to generate such a list: 我创建了一些使用元编程生成这样的列表的代码:
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"))
The criteria for the list is that it should list all non-inherited instance and class methods. 该列表的标准是它应列出所有非继承的实例和类方法。 Constants are indicated with ::
prefix, Class methods are indicated as MyClass::someMethod
and instance methods are indicated as follows: #<MyClass>.someMethod
. 常量用::
前缀表示,类方法表示为MyClass::someMethod
,实例方法表示为: #<MyClass>.someMethod
。
The script above works for the most part however, it misses out Object
and BasicObject
. 上面的脚本大部分都起作用,但是错过了Object
和BasicObject
。 IE in the lists created there are no lines prefixed with #<Object>.
IE在创建的列表中没有以#<Object>.
为前缀的行#<Object>.
or Object::
. 或Object::
。 Am I missing something obvious? 我是否缺少明显的东西?
I suggest you create a hash for each Ruby version and then save that hash or its contents to a file whose name indicates the Ruby version (eg, v_2-5-1.json
or v_2-5-1.txt
) 我建议您为每个Ruby版本创建一个哈希,然后将该哈希或其内容保存到名称指示Ruby版本的文件中(例如, v_2-5-1.json
或v_2-5-1.txt
)
While I don't fully understand the question, you may find he method ObjectSpace::each_object helpful here. 虽然我不完全理解这个问题,但是您可以在这里找到ObjectSpace :: each_object方法。 For example, 例如,
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]
As you see Object
and BasicObject
are two keys (classes) in this hash. 如您所见, Object
和BasicObject
是此哈希中的两个键(类)。 Let's look at the value of one of the keys: Dir
. 让我们看一下其中一个键的值: 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=>[]}
This is for 这是为了
RUBY_VERSION
#=> "2.5.1"
Comparing the contents of this hash with the doc for Dir for v2.5.1 we see that the results are correct for the class Dir
. 将此哈希的内容与Dir for v2.5.1的文档进行比较,我们发现结果对于Dir
类是正确的。
Obtaining constants defined within a class C
is problematic. 获取在类C
定义的常量是有问题的。 C.constants
, which I've used above includes inherited constants. 我上面使用的C.constants
包括继承的常量。 Were I to write C.constants - C.superclass.constants
(mindful that BasicObject.superclass #=> nil
) that would not report inherited constants the are redefined in C
(and redefining an inherited constant does not produce a warning message). 我是在写C.constants - C.superclass.constants
(注意BasicObject.superclass #=> nil
),它不会在C
重新定义继承的常量(并且重新定义继承的常量不会产生警告消息)。
Instead of just looking at classes you may wish to examine all modules ( ObjectSpace.each_object(Module)
) and add a key :is_class
to the hash with value true
or false
): 您可能希望检查所有模块( ObjectSpace.each_object(Module)
),然后将一个键值:is_class
添加到具有true
或false
值的哈希中,而不仅仅是查看类:
There may be other keys you may wish to add to the hash. 您可能希望将其他键添加到哈希中。 :superclass
and :included_modules
(for classes ) are two that comes to mind; :superclass
和:included_modules
(对于classes)是我想到的两个。 :nesting
(for non-class modules) is another. :nesting
(对于非类模块)是另一个。 See Module::nesting . 参见Module :: nesting 。 I suspect that these observations just scratch the surface, that a meaningful comparison of two Ruby versions will be highly complex. 我怀疑这些发现只是表面上的,两个Ruby版本的有意义的比较会非常复杂。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.