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

问题描述 投票:0回答:1

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

module Cars
  module Car1
    BRAND = "TOYOTA"
  end
end

所有这些文件都被一个主文件所需要,在那里我可以做到这一点。

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

我想做的是 puts 所有品牌的所有文件动态,让我只需在第一种格式中新建一个文件(或删除一个文件),就能自动得到打印,而不需要手动添加(或删除) 。

我试着按照这个答案去做 https:/stackoverflow.coma5053119813508702。 但无法实现我的目标。

任何帮助将是apreaciated!

crystal-lang
1个回答
3
投票

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

# 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"]

0
投票

我不知道你是否可以有一个模块的数组 但可以有一个实例的数组!

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
© www.soinside.com 2019 - 2024. All rights reserved.