在下面的Ruby示例中,是否有一种模式让YAML NOT 以静默方式忽略重复键'one'?
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> str = '{ one: 1, one: 2 }'
=> "{ one: 1, one: 2 }"
irb(main):003:0> YAML.load(str)
=> {"one"=>2}
谢谢!
答案 0 :(得分:2)
我帮助维护我使用的YAML文件的一件事是编写代码,以便从Ruby中的已知结构开始生成它。这让我开始了。
然后,我会写一个小片段来加载它并输出它使用PrettyPrint或Awesome Print解析的内容,以便我可以将其与文件进行比较。
我还根据需要对字段进行排序,以便于查找重复项。
答案 1 :(得分:1)
有一个涉及短绒的解决方案,但我不确定它是否与之相关 你,因为它不是100%的Ruby解决方案。因为我不知道,所以我会发布它 任何在Ruby中这样做的方法:
您可以使用yamllint命令行工具:
sudo pip install yamllint
具体来说,它有一个规则key-duplicates
来检测重复的密钥:
$ cat test.yml
{ one: 1, one: 2 }
$ yamllint test.yml
test.yml
1:11 error duplication of key "one" in mapping (key-duplicates)
答案 2 :(得分:0)
没有。您必须决定如何重命名密钥,因为散列键必须是唯一的 - 我会采取一些解决方法,例如手动查找相同的密钥并在执行YAML::load
之前重命名它们。
答案 3 :(得分:0)
使用Psych,您可以遍历AST树以查找重复的键。我在测试套件中使用以下帮助程序方法来验证我的i18n翻译中没有重复的键:
def duplicate_keys(file_or_content)
yaml = file_or_content.is_a?(File) ? file_or_content.read : file_or_content
duplicate_keys = []
validator = ->(node) do
if node.is_a?(Psych::Nodes::Mapping)
duplicates = node.children.select.with_index { |_, i| i.even? }.group_by{ |child| child.value }.select { |value, nodes| nodes.size > 1 }
duplicates.each do |key, nodes|
duplicate_key = {
file: (file_or_content.path if file_or_content.is_a?(File)),
key: key,
occurrences: nodes.map { |occurrence| "line: #{occurrence.start_line + 1}" }
}.compact
duplicate_keys << duplicate_key
end
end
node.children.to_a.each { |child| validator.call(child) }
end
ast = Psych.parse_stream(yaml)
validator.call(ast)
duplicate_keys
end