繁体   English   中英

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

[英]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.

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