Can Ruby's YAML module be used to embed commen

2019-06-27 12:44发布

问题:

The to_yaml method produces nice YAML output, but I would like to include comment lines before some of the elements. Is there a way to do so?

For example, I would like to produce:

# hostname or IP address of client
client: host4.example.com
# hostname or IP address of server
server: 192.168.222.222

From something similar to:

{
  :client => 'host4.example.com',
  :server => '192.168.222.222',
}.to_yaml

... but am not sure if the YAML module even has a way to accomplish.

UPDATE: I ended up not using the solution which used regexes to insert the comments, since it required the separation of the data from the comments. The easiest and most understandable solution for me is:

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

The benefit to me is that nothing is repeated (for example, 'client:' is only specified once), the data and comments are together, the source can be outputted as YAML, and the data structure (available in conf) is available for use.

回答1:

You can do a string replace on all the insertions:

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

output:

--- 
# hostname or IP address of client
:client: host4.example.com
# hostname or IP address of server
:server: 192.168.222.222


回答2:

Something like this:

my_hash = {a: 444}
y=YAML::Stream.new()
y.add(my_hash)
y.emit("# this is a comment")

Of course, you will need to walk the input hash yourself and either add() or emit() as needed. You could look at the source of the to_yaml method for a quick start.