YAMLの参照機能
YAMLに参照機能があるのを、いまさら知ったので、覚書メモ。
* YAMLはちゃんとしたモジュールを使って読み込まないと危険
実験したログ
とあるキー以下を他で再利用したい場合
キーの後ろで「&」をつけて参照用の名前をつけてあげる。
test1.yml
とあるキー: &参照名
Item_A: Item_A_Value
Item_B: Item_B_Value
これをjs-yamlあたりを利用したjsで実行して、構造を出力すると
結果
$ node yamlview.js test1.yml
{ 'とあるキー': { Item_A: 'Item_A_Value', Item_B: 'Item_B_Value' } }
こうなる。
この参照を別のキーとして複写するだけなら
test2.yml
とあるキー: &参照名
Item_A: Item_A_Value
Item_B: Item_B_Value
複写するだけなら: *参照名
結果
$ node yamlview.js test2.yml
{ 'とあるキー': { Item_A: 'Item_A_Value', Item_B: 'Item_B_Value' },
'複写するだけなら': { Item_A: 'Item_A_Value', Item_B: 'Item_B_Value' } }
と中身が複写されてる様にみえる。
データ構造を再びdumpすると
dump結果
$ node yamldump.js test2.yml
とあるキー: &ref_0
Item_A: Item_A_Value
Item_B: Item_B_Value
複写するだけなら: *ref_0
と、リファレンス参照を保持したままになっている。
これだけみてると中身の実体を複写している訳ではなさそう(たぶん)
次に、別のキーにて、とあるキーをベースにしてキーを定義する。
さらに追加したい場合や更新したい場合は中身も記載する。
今回は、
- Item_Aの中身を更新
- Item_Cを追加
します。
test3.yml
とあるキー: &参照名
Item_A: Item_A_Value
Item_B: Item_B_Value
複写するだけなら: *参照名
別のキー:
<<: *参照名
Item_A: Item_AAA_Value
Item_C: Item_C_Value
結果
$ node yamlview.js test3.yml
{ 'とあるキー': { Item_A: 'Item_A_Value', Item_B: 'Item_B_Value' },
'複写するだけなら': { Item_A: 'Item_A_Value', Item_B: 'Item_B_Value' },
'別のキー':
{ Item_A: 'Item_AAA_Value',
Item_B: 'Item_B_Value',
Item_C: 'Item_C_Value' } }
と、複写するだけの部分は先程のリファレンス参照を保持したままだけど、いじったりしている方は、実態を複写してそうにみえる。
更新する場所を、大雑把にやりすぎるとメモリの節約にならないかも?(もちろんデータ定義の手間と品質は良くなるとは思いますが)
参考
準備まわり
参考までにyaml表示するのに利用したnode-jsまわり
$ node init
$ node install js-yaml
使ったスクリプト
yamlview.js
const fs = require('fs');
const jsYaml = require('js-yaml');
try {
const yamlData = fs.readFileSync(process.argv[2], 'utf-8');
const hashData = jsYaml.safeLoad(yamlData);
console.log(hashData);
} catch (e) {
console.log(e);
}
yamldump.js
const fs = require('fs');
const jsYaml = require('js-yaml');
try {
const yamlData = fs.readFileSync(process.argv[2], 'utf-8');
const hashData = jsYaml.safeLoad(yamlData);
const textData = jsYaml.dump(hashData);
console.log(textData);
} catch (e) {
console.log(e);
}