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

如何全局前置Kernel模块的rand方法?期望三类调用均生效

解决方案

要让Kernel.rand、全局rand以及所有对象实例调用的rand都触发自定义逻辑,得同时处理Kernel的实例方法和单例方法——因为rand在Ruby里是双重身份:既是所有对象都能调用的Kernel实例方法,也是可直接通过Kernel.rand/全局rand调用的单例方法。

方法一:用模块前置覆盖两类方法

# 定义包含自定义逻辑的模块
RandHook = Module.new do
  def rand(*args)
    p "do something"
    super(*args)
  end
end

# 覆盖Kernel的实例方法(影响所有对象的rand调用,比如Object.new.send(:rand))
Kernel.prepend(RandHook)

# 覆盖Kernel的单例方法(影响Kernel.rand和全局rand调用)
Kernel.singleton_class.prepend(RandHook)

测试验证:

Kernel.rand            # 打印"do something"并返回随机数
rand                   # 打印"do something"并返回随机数
Object.new.send(:rand) # 打印"do something"并返回随机数

方法二:直接重定义方法(更简洁)

如果不需要保留方法的动态查找逻辑(比如确定不会有其他模块修改rand),可以直接保存原方法后重定义:

# 重定义实例方法
original_instance_rand = Kernel.instance_method(:rand)
Kernel.define_method(:rand) do |*args|
  p "do something"
  original_instance_rand.bind(self).call(*args)
end

# 重定义单例方法
original_singleton_rand = Kernel.method(:rand)
Kernel.define_singleton_method(:rand) do |*args|
  p "do something"
  original_singleton_rand.call(*args)
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:40:03