How to convert a Ruby Hash to YAML and keeping comments?
For the following ruby example
require 'yaml'
h = {
# The garage in Miami
'garage_A' => {
'car_x' => {
# Bought in Gotham
'name' => 'Batmobile',
'color' => 'black'
}
},
'garage_B' => {
# Mike's bike
'bike_m' => {
# Cherry red
'color' => 'red',
'wheels' => 2
}
}
}
puts YAML.dump(h)
I would like to obtain the following result:
---
# The garage in Miami
garage_A:
car_x:
# Bought in Gotham
name: Batmobile
color: black
garage_B:
# Mike's bike
bike_m:
# Cherry red
color: red
wheels: 2
Here is what I'm getting currently:
---
garage_A:
car_x:
name: Batmobile
color: black
garage_B:
bike_m:
color: red
wheels: 2
I could also be interested in the reverse operation.
Use case: A Ruby hash with teh default configuration for a tool. When the configuration file does not exist, it dumps the hash to YAML and write the configuration file. For user-friendlyness it would be better to have the comments in the configuration file rather than to have to refer to the documentation.
Add Comment Keys to Each Hash
You should really template your YAML files as here-documents, or use a templating language like erb. If possible, you should also use more intention-revealing names for your Hash elements so that the comments are unnecessary.
Should you find you still genuinely need the comments, remember that neither JSON nor Ruby Hash objects natively support comments as part of their syntax. As a result, you'll need to create a "comment" key/value pair for each nested object in your Ruby Hash in order to display it within the JSON or YAML you generate from the Hash object. For example:
Now
hash_with_comments.to_yamlwill yield the following YAML:Depending on your use case, you could stop there and just ignore comment keys in whatever code parses the YAML. Otherwise, you can use the String#gsub block syntax (you must use a block to avoid polluting
$1for non-matching lines) to convert the comment elements into actual comments. For example, calling:will yield the following YAML after converting the comment keys to actual comments: