[英]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
。
上面的腳本大部分都起作用,但是錯過了Object
和BasicObject
。 IE在創建的列表中沒有以#<Object>.
為前綴的行#<Object>.
或Object::
。 我是否缺少明顯的東西?
我建議您為每個Ruby版本創建一個哈希,然后將該哈希或其內容保存到名稱指示Ruby版本的文件中(例如, v_2-5-1.json
或v_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]
如您所見, Object
和BasicObject
是此哈希中的兩個鍵(類)。 讓我們看一下其中一個鍵的值: 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
添加到具有true
或false
值的哈希中,而不僅僅是查看類:
您可能希望將其他鍵添加到哈希中。 :superclass
和:included_modules
(對於classes)是我想到的兩個。 :nesting
(對於非類模塊)是另一個。 參見Module :: nesting 。 我懷疑這些發現只是表面上的,兩個Ruby版本的有意義的比較會非常復雜。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.