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
相关产品推荐
相关产品推荐

