2

我正在阅读“Well Grounded Rubyist”一书,我对方法查找路径有疑问:

module M
  def report
    puts "'report' method in module M"
  end
end

module N
  def report
    puts "'report' method in module N"
  end
end

class C
  include M
  include N
  def report
    puts "'report' method in class C"
    puts "About to call super..."
    super
    puts "Back from super..."
  end
end

obj = C.new
obj.report

根据我的理解,obj.report 会输出:

'report' method in class C
About to call super...
'report' method in module N
Back from super...

但是,我很好奇是否可以通过在类 C 中绕过 N 的报告来调用 M 的报告方法。我知道如果我在模块 N 中添加“super”,它将调用 N 的报告,然后是 M 的报告,然后再放入“从超级回来......”但是有没有办法直接从 C 中做到这一点?

4

2 回答 2

3

您可以使用祖先反射:

class C
  def report
    my_ancestors = self.class.ancestors
    puts "my ancestors are: #{my_ancestors}"
    method = my_ancestors[2].instance_method(:report)
    method.bind(self).call
  end
end

C.new.report
=> my ancestors are: [C, N, M, Object, PP::ObjectMixin, Kernel, BasicObject]
=> 'report' method in module M
于 2013-01-29T01:05:42.660 回答
1

这可行,但我觉得必须有更好的方法来做到这一点,而无需将其更改为 self:

module M
   def self.report
      puts "'report' method in module M"
   end
end

Class C
include M
include N
def report
   puts "'report' method in class C"
   puts "About to call M.report..."
   M.report
   puts "About to call super..."
   super
    puts "Back from super..."
 end
 end

输出将是:

'report' method in class C
About to call M.report...
'report' method in module M
About to call super...
'report' method in module N
Back from super...
于 2013-01-29T00:57:49.833 回答