Ruby YAML多个文档

lab*_*cd6 5 ruby yaml documents

这是我的YAML文件'test.yml':

---
alpha: 100.0
beta: 200.0
gama: 300.0
--- 3
...
Run Code Online (Sandbox Code Playgroud)

第一个文档是哈希.

第二个文档是整数.

我试图将这些加载到Ruby程序中作为哈希和整数.

这是我目前的尝试:

require 'yaml'

variables = YAML.load_file('test.yml')
puts variables.inspect
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 18

要在单个文件中访问多个YAML文档,请使用该load_stream方法(在评论中已经通过"matt"提及其他答案之一):

YAML.load_stream('test.yml') do |document|
    puts document
end
Run Code Online (Sandbox Code Playgroud)


Pen*_*lor 6

锡人是正确的,OP不应该为他的具体问题使用多个文件; 但是,YAML流中的多个文档的情况确实在实践中发生,例如当多个YAML文档附加到单个文件时,因此值得知道如何处理它.

require 'yaml'

yaml = <<EOT
---
alpha: 100.0
beta: 200.0
gama: 300.0
---
int: 3
...
EOT

loop do
  puts YAML.load(yaml)
  break if !yaml.sub!(/(?<!#)(-{3}.+?(?=-{3})\n?){1}/m,'')
  break if yaml.empty?
end

# >> {"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0}
# >> {"int"=>3}
Run Code Online (Sandbox Code Playgroud)

  • 你应该只使用[`load_stream`](http://ruby-doc.org/stdlib-2.1.0/libdoc/psych/rdoc/Psych.html#method-c-load_stream)而不是自己这样做(注意`Psych`常数与当前Rubys中的'YAML`相同). (8认同)
  • 不幸的是,[YAML](http://ruby-doc.org/stdlib-2.1.0/libdoc/yaml/rdoc/YAML.html)的ruby-doc页面没有提供Psych文档的链接.它甚至没有提到公共接口比`load`,`dump`和`to_yaml`更多. (2认同)

the*_*Man -4

不要使用多个文档;它们不能替代定义数据中的各个元素:

require 'yaml'

yaml = <<EOT
---
hash:
  alpha: 100.0
  beta: 200.0
  gama: 300.0
int: 3
EOT

YAML.load(yaml)   
# => {"hash"=>{"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0}, "int"=>3}
Run Code Online (Sandbox Code Playgroud)

YAML.load(yaml)您可以通过分配给变量来访问内容:

data = YAML.load(yaml)
data['hash'] # => {"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0}
data['int'] # => 3
Run Code Online (Sandbox Code Playgroud)

可以这样想,在解析 YAML 文件后,您会从 YAML 中请求某种类型的对象。您需要能够从中提取特定值,因此您可以轻松地定义一个包含您想要的内容的数组或哈希,在 YAML 的限制和规范范围内,以您大脑的工作方式。

如果我要创建一个复杂的结构,我首先在 Ruby 中完成,并让 YAML 为我转储格式:

require 'yaml'

data = {
  "hash" => {
    "alpha" => 100.0,
    "beta" => 200.0,
    "gama" => 300.0
  },
  "int" => 3
}

puts data.to_yaml

# >> ---
# >> hash:
# >>   alpha: 100.0
# >>   beta: 200.0
# >>   gama: 300.0
# >> int: 3
Run Code Online (Sandbox Code Playgroud)

我可以将 Ruby 代码放入脚本中并运行它,将其重定向到 YAML 文件:

ruby test.rb > test.yaml
Run Code Online (Sandbox Code Playgroud)

然后我可以扩展结构:

require 'yaml'

data = {
  "hash" => {
    "alpha" => 100.0,
    "beta" => 200.0,
    "gama" => 300.0
  },
  "int" => 3,
  "array" => %w[a b c]
}

puts data.to_yaml

# >> ---
# >> hash:
# >>   alpha: 100.0
# >>   beta: 200.0
# >>   gama: 300.0
# >> int: 3
# >> array:
# >> - a
# >> - b
# >> - c
Run Code Online (Sandbox Code Playgroud)

往返测试:

require 'yaml'

yaml = <<EOT
---
hash:
  alpha: 100.0
  beta: 200.0
  gama: 300.0
int: 3
array:
- a
- b
- c
EOT

YAML.load(yaml)
# => {"hash"=>{"alpha"=>100.0, "beta"=>200.0, "gama"=>300.0}, "int"=>3, "array"=>["a", "b", "c"]}
Run Code Online (Sandbox Code Playgroud)

反复执行此操作,直到您熟悉 YAML 语法,然后您可以手动构建/调整 YAML 文件。

现在,我们来看看它有多聪明。YAML 规范支持别名,这让我们可以定义一个变量,然后分别使用&和多次重用它*。当您的文档变大时,手动创建这些内容会很痛苦,但 YAML 驱动程序很聪明,会为您输出它们:

require 'yaml'

FOO = ['foo']
BAR = ['bar']

foobar = [FOO, BAR]

data = {
  "foo" => FOO,
  'bar' => BAR,
  'foobar' => foobar,
}

puts data.to_yaml


# >> ---
# >> foo: &1
# >> - foo
# >> bar: &2
# >> - bar
# >> foobar:
# >> - *1
# >> - *2
Run Code Online (Sandbox Code Playgroud)

foo: &1定义["foo"],并在底部重用为*1

YamlForRuby 站点上的 Yaml Cookbook ” 是使用 YAML 的一个很好的参考。

  • 在某些合理的用例中,您可能希望使用多个文档。例如文档流。 (4认同)
  • 当然,那么通过指出在这种特定情况下多个文档可能不是正确的方法来尝试使答案更精确可能会很有用。我主要在想第一句话,听起来很激烈。 (2认同)