You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby 2.7+如何编程识别super调用链中当前方法所属混入模块

适用版本

Ruby 2.7+

问题描述

多个通过mixin机制混入类的模块如果定义了同名方法,调用时这些方法会通过super关键字沿方法链依次触发,所有混入模块中的同名方法都会执行。需要通过编程方式(非硬编码)识别当前运行的方法所属的混入来源模块,替换示例代码中的占位输出。
原示例代码如下:

module A
  def initialize(*args, **kwargs)
    puts("something magic")
  end
end
module B
  def initialize(*args, **kwargs)
    puts("something magic")
  end
end

class C
  include A
  include B

  def initialize(*args, **kwargs)
    puts("actual #{self.class.name} initialize")
    super
  end
end

运行上述代码会输出三行内容,需要找到类似self.class.name、可对应到具体模块的属性,识别当前运行的initialize方法由哪个模块提供。

实现方案

在方法内部通过method(__method__).owner即可获取当前执行方法的原始定义所属模块/类,调用该对象的name方法就能拿到对应的模块名。
修改后的可运行代码:

module A
  def initialize(*args, **kwargs)
    puts("initialize from #{method(__method__).owner.name}")
    super
  end
end
module B
  def initialize(*args, **kwargs)
    puts("initialize from #{method(__method__).owner.name}")
    super
  end
end

class C
  include A
  include B

  def initialize(*args, **kwargs)
    puts("actual #{self.class.name} initialize")
    super
  end
end

C.new

运行输出结果:

actual C initialize
initialize from B
initialize from A

补充说明:Ruby模块混入的方法调用顺序实际是确定的,遵循后混入优先规则,最后执行include的模块会排在方法查找链更靠前的位置,会更早被触发。


内容的提问来源于stack exchange,提问作者RoUS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:09:18