[英]Getting ordered list of class/modules implementing instance methods for method inheritance order/super
我在Ruby類(在Ruby 2.0.0p247中)中包含了幾個模塊,其中一些模塊定義了相同的實例方法,並且都包含在同一類中。 我想要一些代碼來為實現該方法的繼承層次結構中的類列表生成每個方法名稱符號的哈希值。 我該怎么辦?
(這樣一來,我知道當我調用每個x
方法時,如果每個x
方法都super if defined?(super)
,那么我知道方法的執行順序。)
例如,給定實現實例方法x的類C,其中C包括均實現實例方法x的模塊A和B,那么我可以使用一些代碼來檢查C以產生類似以下結果:
=> {:x=>[C, A, B], ...}
為了澄清,我想知道所有通過模塊和類繼承繼承的方法,而不僅僅是在C上定義的方法。
另一個顯示我在尋找什么的示例:
module A
def v
end
def x
end
end
module B
def x
end
def y
end
end
module D
def a
end
end
class E
include A, B
def x
end
def y
end
def z
end
end
class C < E
include D
end
為此,C的結果應為:
=> {:a=>[D], :x=>[E, A, B], :y=>[E, B], :z=>[E], :v=>[A], :nil?=>[Kernel], :====>[Kernel], :=~=>[Kernel], :!~=>[Kernel], :eql?=>[Kernel], :hash=>[Kernel], :<=>=>[Kernel], :class=>[Kernel], :singleton_class=>[Kernel], :clone=>[Kernel], :dup=>[Kernel], :taint=>[Kernel], :tainted?=>[Kernel], :untaint=>[Kernel], :untrust=>[Kernel], :untrusted?=>[Kernel], :trust=>[Kernel], :freeze=>[Kernel], :frozen?=>[Kernel], :to_s=>[Kernel], :inspect=>[Kernel], :methods=>[Kernel], :singleton_methods=>[Kernel], :protected_methods=>[Kernel], :private_methods=>[Kernel], :public_methods=>[Kernel], :instance_variables=>[Kernel], :instance_variable_get=>[Kernel], :instance_variable_set=>[Kernel], :instance_variable_defined?=>[Kernel], :remove_instance_variable=>[Kernel], :instance_of?=>[Kernel], :kind_of?=>[Kernel], :is_a?=>[Kernel], :tap=>[Kernel], :send=>[Kernel], :public_send=>[Kernel], :respond_to?=>[Kernel], :extend=>[Kernel], :display=>[Kernel], :method=>[Kernel], :public_method=>[Kernel], :define_singleton_method=>[Kernel], :object_id=>[Kernel], :to_enum=>[Kernel], :enum_for=>[Kernel], :===>[BasicObject], :equal?=>[BasicObject], :!=>[BasicObject], :!==>[BasicObject], :instance_eval=>[BasicObject], :instance_exec=>[BasicObject], :__send__=>[BasicObject], :__id__=>[BasicObject]}
Hash[
C.instance_methods.map {|m|
[m, C.ancestors.select {|a| a.instance_methods(false).include?(m)}]}]
# => { x: [C, A, B] }
我的第一次嘗試是:
instance_method_inheritance_chain = {}
C.instance_methods(false).each do |m|
(instance_method_inheritance_chain[m] ||= []) << C
end
C.ancestors.each do |a|
a.instance_methods(false).each do |m|
(instance_method_inheritance_chain[m] ||= []) << a unless instance_method_inheritance_chain[m] && instance_method_inheritance_chain[m].include?(a)
end
end
instance_method_inheritance_chain
但是,以約爾格的答案為起點來縮短我以前的答案,我想到了:
result = Hash[C.instance_methods(false).map {|m| [m, [C]]}]
C.ancestors.each {|a| a.instance_methods(false).each {|m| (result[m] ||= []) << a } }
result
或作為一種方法:
def method_inheritance(klass)
result = Hash[klass.instance_methods(false).map {|m| [m, [klass]]}]
klass.ancestors.each {|a| a.instance_methods(false).each {|m| (result[m] ||= []) << a } }
result # and maybe .reject{|m| m == :method_inheritance} if needed
end
method_inheritance(C)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.