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

Ruby中如何获取引入自定义module的类名以读取对应JSON文件

问题1:为什么模块顶层的puts只执行一次

Ruby中模块定义内部的顶层代码,仅会在模块首次被解释器加载解析时执行1次,后续任何类include该模块的操作,都不会重新运行模块顶层的代码。此时顶层代码的self指向模块A本身,所以输出的名称是A,自然也不可能拿到后续引入模块的类名。

问题2:实现按引入类名加载JSON、动态定义方法/常量的方案

你所有的动态逻辑都可以在self.included钩子内完成,这个钩子每次有类引入模块时都会触发,参数就是当前引入模块的类对象,示例实现如下:

require 'json'

module A
  def self.included(clazz)
    # 拼接对应JSON文件名
    json_path = "#{clazz.name}.json"
    # 读取解析JSON,可自行添加文件不存在的异常处理
    config = JSON.parse(File.read(json_path)) rescue {}

    # 给目标类设置类级实例变量,每个引入类独立存储
    clazz.instance_variable_set(:@module_a_config, config)

    # 给目标类定义常量
    clazz.const_set(:A_CONFIG, config)

    # 给目标类定义实例方法
    clazz.define_method :a_config do
      config
    end

    # 给目标类定义类方法
    clazz.define_singleton_method :a_config do
      config
    end
  end
end

class B
  include A
end

class C
  include A
end

# 测试效果
puts B::A_CONFIG # 输出B.json的内容
puts B.new.a_config # 输出B.json的内容
puts C.a_config # 输出C.json的内容

注意事项

如果需要给每个引入类设置独立的类级别变量,不要直接在included钩子内写@变量名,此时self指向模块A,变量会被所有引入类共享,需要通过clazz.instance_variable_set操作目标类的变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 17:06:00