【问题标题】:List of defined super methods for a certain class method in rubyruby 中某个类方法定义的超级方法列表
【发布时间】:2013-06-21 19:20:11
【问题描述】:

我正在开发一个具有一些复杂类/mixin 层次结构的系统。由于有许多层分散在许多不同的文件中,我想快速查看给定方法的超级调用链。

例如

module AAA
  def to_s
    "AAA " + super()
  end
end

module BBB
  def to_s
    "BBB " + super()
  end
end

class MyArray < Array
  include AAA
  include BBB

  def to_s
    "MyArray " + super()
  end
end

> MyArray.new.to_s
=> "MyArray BBB AAA []"
> method_supers(MyArray,:to_s)
=> ["MyArray#to_s", "BBB#to_s", "AAA#to_s", "Array#to_s", ...]

【问题讨论】:

  • 如果有人想到更好的标题,请告诉我。

标签: ruby inheritance reflection mixins super


【解决方案1】:

也许是这样的?

class A
  def foo; p :A; end
end

module B
  def foo; p :B; super; end
end

module C; end

class D < A
  include B, C
  def foo; p :D; super; end
end

p D.ancestors.keep_if { |c| c.instance_methods.include? :foo }  # [D, B, A]

如果这看起来正确,您可以相应地修改此函数:

def Object.super_methods(method)
  ancestors.keep_if { |c| c.instance_methods.include? method }
end

p D.super_methods(:foo)  # [D, B, A]

【讨论】:

    【解决方案2】:
    def method_supers(child_class,method_name)
      ancestry = child_class.ancestors
    
      methods = ancestry.map do |ancestor|
        begin
          ancestor.instance_method(method_name)
        rescue
          nil
        end
      end
    
      methods.reject!(&:nil?)
    
      methods.map {|m| m.owner.name + "#" + m.name.to_s}
    end
    

    【讨论】:

    • 你的代码可以改进,所以你为什么不把它放在问题本身,在这里问人们其他选择或改进你的代码。
    • 因为它是一个答案。没有什么能阻止人们发布另一篇文章或发表评论以提出改进建议。为什么不提出改进建议?
    • @OMG 我认为如果有一个网站可以让您提交代码并让现场人员审查它并通过评论它并告诉您他们如何帮助您改进会以不同的方式解决问题,优化它,甚至只是针对该特定语言采用更标准化的方法,因为当我第一次开始学习 ruby​​ 时,我试图纠正 for 循环而不是 .each 循环。
    • @ratelle 我同意这是一个答案和帮助别人的起点,它不一定是你写过的最好的东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 2016-06-30
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    相关资源
    最近更新 更多