可以使用Ruby的YAML模块嵌入注释吗?

时间:2013-01-04 00:43:43

标签: ruby yaml to-yaml

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中可用)可以使用。

3 个答案:

答案 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不会像他们认为的那样缩进数组。)