简体   繁体   English

获取实现实例方法的类/模块的有序列表,以实现方法继承order / super

[英]Getting ordered list of class/modules implementing instance methods for method inheritance order/super

I'm including several modules in a Ruby class (in Ruby 2.0.0p247), some that define the same instance method and are all included in the same class. 我在Ruby类(在Ruby 2.0.0p247中)中包含了几个模块,其中一些模块定义了相同的实例方法,并且都包含在同一类中。 I'd like some code to generate a hash of each method name symbol to the list of classes in the inheritance hierarchy that implement that method, in order that they would be executed. 我想要一些代码来为实现该方法的继承层次结构中的类列表生成每个方法名称符号的哈希值。 How would I do that? 我该怎么办?

(That way I know when I call each x method, if each were to do super if defined?(super) , I know the order of method execution.) (这样一来,我知道当我调用每个x方法时,如果每个x方法都super if defined?(super) ,那么我知道方法的执行顺序。)

Eg given class C that implements instance method x, where C includes modules A and B that both implement instance method x, then I could use some code to inspect C to result in something like: 例如,给定实现实例方法x的类C,其中C包括均实现实例方法x的模块A和B,那么我可以使用一些代码来检查C以产生类似以下结果:

=> {:x=>[C, A, B], ...}

To clarify, I want to know all of the methods that are inherited through modules and class inheritance, not just those that were defined on C. 为了澄清,我想知道所有通过模块和类继承继承的方法,而不仅仅是在C上定义的方法。

Another example to show what I'm looking for: 另一个显示我在寻找什么的示例:

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

For that the result for C should be: 为此,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] }

My first attempt was: 我的第一次尝试是:

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

But, using Jörg's answer as a starting point to shorten my previous answer, I came up with: 但是,以约尔格的答案为起点来缩短我以前的答案,我想到了:

result = Hash[C.instance_methods(false).map {|m| [m, [C]]}]
C.ancestors.each {|a| a.instance_methods(false).each {|m| (result[m] ||= []) << a } }
result

or as a method: 或作为一种方法:

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.

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