Ruby如何重写依赖gem中继承自父类的完整类
实现方案
你可以通过先移除原有类常量再重新定义的方式完全替换gem内的类,Ruby的动态特性支持这种操作,步骤如下:
- 先保证
blahgem已经完全加载完成后再执行重写代码:Rails项目可以将代码放在config/initializers目录下的自定义初始化文件中,普通Ruby项目要在require 'blah'之后执行重写逻辑。 - 删除Ruby已加载的原有
foo类常量,否则直接重新定义会保留原有继承关系无法修改。 - 自定义你需要的
foo类逻辑即可。
示例代码
# 确保gem已加载 require "blah" # 移除原有foo常量,存在才执行避免报错 Object.send(:remove_const, :foo) if Object.const_defined?(:foo) # 重新定义你需要的foo类 class foo < not_bar def a_different_some_method # 自定义逻辑 end def a_different_another_method # 自定义逻辑 end end
注意事项
- 该方案会完全替换原gem的
foo类,gem内部所有调用foo的位置都会自动使用你新定义的类,如果原gem有依赖foo < bar的逻辑可能出现兼容问题,上线前需要做好充分测试。 - 如果
foo类在gem的命名空间下(比如Blah::foo),需要调整常量删除和类定义的写法:# 删除命名空间下的常量 Blah.send(:remove_const, :foo) if Blah.const_defined?(:foo) # 定义命名空间下的自定义类 class Blah::foo < not_bar # 自定义方法 end - 如果不需要修改继承关系只是修改类方法/实例方法,直接重开类或者用
Module#prepend覆写对应方法即可,不需要删除原有常量。
内容的提问来源于stack exchange,提问作者dillonb
相关产品推荐
相关产品推荐

