如何将YAML文件读入哈希

时间:2018-07-20 10:08:20

标签: crystal-lang

我需要将YAML配置文件从磁盘读取为内存,作为Crystal中的哈希。 (尽管我感到有些困惑,但我知道this在邮件列表中对该主题的讨论。)

我尝试读取的YAML文件是一个相当简单的配置文件:

---
:excludes:
  - Stage
  - Class
  - Anchor
  - Notify
  - Node
  - /::/
:only_include: []
:md5sums: false
:class_name: null
:catalog_file: null
:output_file: spec/classes/init_spec.rb
:compile_test: true
:setup: {}

一个代码示例,展示了如何使用Crystal 0.25将YAML配置文件从磁盘读取到Hash中。

2 个答案:

答案 0 :(得分:4)

这是最好的方法。

    require "yaml"

    class Config
      include YAML::Serializable

      @[YAML::Field(key: ":excludes")]
      property excludes : Array(String)

      @[YAML::Field(key: ":only_include")]
      property only_include : Array(String)

      @[YAML::Field(key: ":md5sums")]
      property md5sums : Bool

      @[YAML::Field(key: ":class_name")]
      property class_name : String?

      @[YAML::Field(key: ":catalog_file")]
      property catalog_file : String?

      @[YAML::Field(key: ":output_file")]
      property output_file : String

      @[YAML::Field(key: ":compile_test")]
      property compile_test : Bool

      @[YAML::Field(key: ":setup")]
      property setup : Hash(String, String)
    end

    yaml = <<-YAML
    :excludes:
      - Stage
      - Class
      - Anchor
      - Notify
      - Node
      - /::/
    :only_include: []
    :md5sums: false
    :class_name: null
    :catalog_file: null
    :output_file: spec/classes/init_spec.rb
    :compile_test: true
    :setup: {}
    YAML

    p Config.from_yaml(yaml)

请注意,Crystal中的YAML当前不支持从YAML创建正则表达式,因此您可能希望在解析后执行此操作(对于转换器而言,这有点棘手)。

答案 1 :(得分:2)

我不确定,这个简单的示例是否可以帮助您,但也许会给出一些提示:

yaml = File.open("conf.yml") { |file| YAML.parse(file) }
yaml.class                         # => YAML::Any
hash = yaml.as_h                   # As you can see below, it gives a Hash, but with YAML::Any underneath
hash.class                         # => Hash(YAML::Any, YAML::Any)
yaml[":excludes"].as_a.first       # => "Stage"
yaml[":md5sums"] == false          # => true
yaml[":output_file"].as_s + "-FOO" # => "spec/classes/init_spec.rb-FOO"
yaml[":setup"].as_h.class          # => Hash(YAML::Any, YAML::Any)

因此,您需要记住YAML是数据的来源,不要忘记使用.as_*方法将其转换为所需的类型。