私はよく、アプリの大規模な構成用に YAML ジェネレーターを作成します。メンテナンスのために、フィールドをソートする必要があります。
ソートされた順序で YAML を生成するときに使用する解決策は、必要に応じてキーを追加して、正しいハッシュまたはサブハッシュでキーを取得することです。次に、キーと値のペアを並べ替えて新しいハッシュを作成し、to_yaml
それに対して実行します。
ハッシュをソートする意味はありませんが、YAML に機能させる前に一時ハッシュを出力するようにソートすると、ファイルの管理が容易になります。
require 'yaml'
some_hash = {
'z' => 1,
'a' => 3
}
puts some_hash.to_yaml
どの出力:
---
z: 1
a: 3
YAML 出力を作成する前に並べ替えます。
puts Hash[some_hash.merge('x' => 2).sort_by{ |k, v| k }].to_yaml
出力:
---
a: 3
x: 2
z: 1
の代わりに、に渡されるブロックに行をputs
使用または埋め込みます。File.write
File.open
YAML ファイルのコメントについて: YAML は、発行された出力にプログラムでコメントを追加することをサポートしていません。コメントは人間用であり#
、Ruby 変数またはオブジェクトにマップできません。このように考えてください: というファイルでこの YAML から始めるとtest.yaml
:
---
# string
a: 'fish'
# array
b:
- 1
- 2
# hash
c:
d: 'foo'
e: 'bar'
# integer
z: 1
そしてそれをロードします:
require 'pp'
require 'yaml'
obj = YAML.load_file('test.yaml')
pp obj
私は次のobj
ようになります:
{"a"=>"fish", "b"=>[1, 2], "c"=>{"d"=>"foo", "e"=>"bar"}, "z"=>1}
返される「コメント」オブジェクトはなく、YAML 仕様に存在するハッシュに適合する Ruby には存在しません。Comment と呼ばれるクラスを任意に作り、それをオブジェクトにキーとして埋め込むこともできますが、YAML はそれをコメントとして受け入れません。これは、仕様で許可されていないためです。それを Ruby クラスとして定義し、そのクラスとして再作成しますが、#
コメントとして表示されません。
require 'yaml'
class Comment
def initialize(some_text)
@comment = "# #{some_text}"
end
end
some_hash = {
'a' => 1,
Comment.new('foo') => 'bar',
'z' => 'z'
}
puts some_hash.to_yaml
出力:
---
a: 1
? !ruby/object:Comment
comment: ! '# foo'
: bar
z: z
発行された YAML 構成にコメントが必要な場合は、手動で微調整して後で追加します。手動で微調整するのではなく、やりたいことのために、文書内でスキャンできる、より記憶に残る名前または一意の変数名を使用することをお勧めします。プレースホルダーとして機能すること以外に価値のあるものを提供しないダミーエントリを入れることもできます:
require 'yaml'
some_hash = {
'a' => 1,
'__we_are_here__' => '',
'b' => 2,
'__we_are_now_here__' => '',
'z' => 'z'
}
puts some_hash.to_yaml
次のような YAML ファイルが生成されます。
---
a: 1
__we_are_here__: ''
b: 2
__we_are_now_here__: ''
z: z
キーをハッシュに挿入する限り、「キーチェーン」を少し再構築して、挿入するパスと新しいキーの名前を表示します。繰り返しになりますが、YAML を保存する前に、並べ替えを使用して正しい順序になっていることを確認します。
require 'pp'
# this changes the incoming hash
def insert_embedded_hash_element(hash, key_path, new_value)
keys = key_path.split('.')
new_key = keys.pop
sub_hash = hash
keys.each do |k|
sub_hash = sub_hash[k]
end
sub_hash[new_key] = new_value
end
# the sub-hash to insert into + new key name
insert_key = 'nested.key2'
insert_value = 'new_value'
hash = {
"some_key" => "value",
"nested" => {
"key1" => "val1",
"key3" => "val2"
}
}
insert_embedded_hash_element(hash, insert_key, insert_value)
pp hash
その結果:
{"some_key"=>"value",
"nested"=>{"key1"=>"val1", "key3"=>"val2", "key2"=>"new_value"}}