to_yaml方法产生了很好的YAML输出,但是我希望在某些元素之前包含注释行。有办法吗?
例如,我想制作:
# hostname or IP address of client
client: host4.example.com
# hostname or IP address of server
server: 192.168.222.222
类似于:
{
:client => 'host4.example.com',
:server => '192.168.222.222',
}.to_yaml
...但我不确定YAML模块是否有办法完成。
更新:我最终没有使用使用正则表达式插入注释的解决方案,因为它需要将数据与注释分开。对我来说最简单,最容易理解的解决方案是:
require 'yaml'
source = <<SOURCE
# hostname or IP address of client
client: host4.example.com
# hostname or IP address of server
server: 192.168.222.222
SOURCE
conf = YAML::load(source)
puts source
对我来说好处是没有重复(例如,'client:'只指定一次),数据和注释在一起,源可以作为YAML输出,数据结构(在conf中可用)可以使用。
答案 0 :(得分:3)
您可以对所有插入执行字符串替换:
require 'yaml'
source = {
:client => 'host4.example.com',
:server => '192.168.222.222',
}.to_yaml
substitution_list = {
/:client:/ => "# hostname or IP address of client\n:client:",
/:server:/ => "# hostname or IP address of server\n:server:"
}
substitution_list.each do |pattern, replacement|
source.gsub!(pattern, replacement)
end
puts source
输出:
---
# hostname or IP address of client
:client: host4.example.com
# hostname or IP address of server
:server: 192.168.222.222
答案 1 :(得分:2)
这样的事情:
my_hash = {a: 444}
y=YAML::Stream.new()
y.add(my_hash)
y.emit("# this is a comment")
当然,您需要自己处理输入哈希,并根据需要add()
或emit()
。
您可以查看to_yaml
方法的来源,以便快速入门。
答案 2 :(得分:1)
这不是完美的方法(例如,没有中级阵列支持),但是它可以满足我的需求。
def commentify_yaml(db)
ret = []
db.to_yaml(line_width: -1).each_line do |l|
if l.match(/^\s*:c\d+:/)
l = l.sub(/:c(\d+)?:/, '#').
sub(/(^\s*# )["']/, '\1').
sub(/["']\s*$/, '').
gsub(/''(\S+?)''/, "'\\1'").
gsub(/(\S)''/, "\\1'")
end
ret << l.chomp
end
ret * "\n"
end
示例用法。
commentify_yaml(
{
c1: 'Comment line 1',
c2: 'Comment line 2',
'hash_1' => {
c1: 'Foo',
c2: 'Bar',
'key_1' => "Hello!",
},
'baz' => qux,
c3: 'Keep up-numbering the comments in the same hash',
'array_1' => [
1,
2,
3
]
}
)
==>
# Comment line 1
# Comment line 2
hash_1:
# Foo
# Bar
key_1: "Hello!"
baz: "Value of qux"
# Keep up-numbering the comments in the same hash
array_1:
- 1
- 2
- 3
(注意:Syck不会像他们认为的那样缩进数组。)