Crystal - 如何从多个文件中的模块动态获取全局变量

Crystal - How to dynamically get global variables from modules in multiple files

我有多个这种格式的文件: car1.cr

module Cars
  module Car1
    BRAND = "TOYOTA"
  end
end

主文件需要所有这些文件,我可以在其中执行此操作:

puts Cars::Car1::BRAND #=> TOYOTA

我想做的是 puts 所有文件的所有品牌动态地,允许我以第一种格式创建一个新文件(或删除一个文件)并自动打印无需手动添加(或删除)。

我尝试遵循这个答案,但未能实现我的目标。

如有任何帮助,我们将不胜感激!

你真的需要常量吗?您的文件不能只是建立一个哈希值吗?

# cars.cr
module Cars
  BRANDS = {} of String, String
end

# car1.cr
module Cars
  module Car1
    BRANDS["Car1"] = "TOYOTA"

    # Or if you really need the constant
    BRAND = "TOYOTA"
    BRANDS["Car1"] = BRAND
  end
end

# Or if it really just defines the data
Cars::BRANDS["Car1"] = "TOYOTA"

我怀疑你收集的信息比品牌多,所以你可以定义一个值类型:

module Cars
  record Car, name : String, brand : String, model : String

  CARS = [] of Car
end

Cars::CARS << Car.new("Car1", "TOYOTA", "AA")

这里的一般答案是,试着想办法重构你的程序,这样你就不需要这种元编程能力了。这通常会导致更清晰、更易于遵循的代码。

回答实际问题:

module Cars
  module Car1
    BRAND = "TOYOTA"
  end

  module Car2
    BRAND = "HONDA"
  end

  def self.collect_brands
    {{@type.constants.map {|car| "#{car}::BRAND".id }}}
  end
end

Cars.collect_brands # => ["TOYOTA", "HONDA"]

如果有帮助,我不知道您是否可以拥有模块数组但实例数组!

module Car
  abstract def brand : String
end

BRANDS = [] of Car

module Cars
  class Car1
    include Car
    def brand : String
      "TOYOTA"
    end
  end
end

BRANDS << Cars::Car1.new