YAML confファイルの中にハッシュをマージする

によって2009年7月31日プラシャント
の下でファイルされる: 技術

YAMLは設定ファイルを書くために非常に便利です。 主な利点は、それがテキストフ​​ァイルのように読むことです。 configファイル(無階層)平らでない繰り返しを持っていない場合、これは本当によく働く。
あなたのコンフィギュレーションファイルが繰り返しがある場合、それはそれらの要素を分離し、それらを再利用することは理にかなっています。 私は何を意味することはこれである - のは、configファイルは、次のようになりますことを言ってみましょう:

 開発:
   input_location:common_input
   output_location:dev_location
  メールアドレス:
     smtp_server:YOUR_SERVER
    ログイン:your_login
    パスワード:top_secret
生産:
   input_location:common_input
   output_location:dev_location
  メールアドレス:
     smtp_server:YOUR_SERVER
    ログイン:your_login
    パスワード:top_secret 

ここでは/ tmp / test.ymlで上記のコードと仮定すると、PythonやRubyで読むことができる方法です。
$cat readyml.py

 #!/ usr / bin / envをのpython
 PPとして出力の整然化のインポート出力の整然化から
 #Debianでのpython-yamlをインストールする必要があります
 YAMLインポート負荷から、load_all、ダンプ
ハッシュをかざすと(開いている( 'は/ tmp / test.yml'))
 PP(ハッシュ['開発']) 


$ cat readyml.rb

  #!/ usr / bin / envをルビー
 "PP"を必要とする
ハッシュ= YAML ::負荷(File.open( '/ tmpに/ test.yml')は。読む)
 ppはハッシュ['開発'] 

ここでルビーバージョンの便利な1ライナーです。
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]'またはIRBやPythonコンソールで同じことを試してみることができます。

上記のコードスニペットでは、すべてが出力場所は、開発と生産の部分で同じである以外のことに注意してください。 YMLノード識別子が救出に来る場所です。 アイデアは単純なデフォルト値のセットを持っていると別の場所でそれらを上書きします。
次のように、あなたはそれを引き離すこともできます。

 デフォルト値:&デフォルト
   input_location:common_input
   output_location:dev_location
  メールアドレス:
     SENDER_NAME:送信
     smtp_server:YOUR_SERVER
    ログイン:your_login
    パスワード:top_secret
開発:
   <<:*デフォルト
生産:
   <<:*デフォルト
   output_location:prod_location 


$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$

偉大な、それは(TM)の動作!
間違いなく我々は魔法のビットのいくつかの明快さを交換した。 ここで小さな説明は、次のとおりです。&、*と。<<&アンカー·タグであるが、ノードの識別子として理解することができます*は、ノードの参照と<<次のとおりです。ハッシュ結合を表しています。

詳細については、いずれかを参照してくださいYAML仕様またはWikipediaを
これまでのところは良いが、漁獲量はここにありますが、これらのハッシュのマージは再帰的ではありません。 それは何を意味すると、この次のとおりです。ましょうあなたが2つの環境でメールを別の送信者名を持ちたいと言うあなたは、次の操作を行うように誘惑される場合があります。

 デフォルト値:&デフォルト
   input_location:common_input
   output_location:dev_location
  メールアドレス:
     SENDER_NAME:送信
     smtp_server:YOUR_SERVER
    ログイン:your_login
    パスワード:top_secret
開発:
   <<:*デフォルト
  メールアドレス:
     SENDER_NAME:sender_dev
生産:
   <<:*デフォルト
   output_location:prod_location
  メールアドレス:
     SENDER_NAME:sender_prod 

確認することができます

$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$

おっと、何かが間違っていた、前述したようにこの問題は、ハッシュ結合が再帰的ではないということですとマージ中には1つだけ鍵を持っている生産のメールで、デフォルトの電子メールに取って代わりました。 解決策/回避策は複数のレベルをアンロールすることです。

  common_settings:&common_settings
 input_location:common_input
 output_location:dev_location
 mail_defaults:&mail_defaults
  SENDER_NAME:送信
   smtp_server:YOUR_SERVER
  ログイン:your_login
  パスワード:top_secret

デフォルト値:&デフォルト
   <<:* common_settings
  メールアドレス:
     <<:* mail_defaults
開発:
   <<:*デフォルト
生産:
   <<:*デフォルト
  メールアドレス:
     <<:* mail_defaults
     SENDER_NAME:sender_prod

再度確認することができます

$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$

あなたが入れ子の複数レベルを持って言った、よくあなたは間違いなく、複数のレベルを展開することができますが、それは混乱になります。 あなたは、confファイルにハノイの塔への解決策を記述しようとしていない場合ので、それはYAMLもしくは他の何かを掘り下げるよりも、confファイルをrestuctureすることをお勧めします。 しかし、それはとにかくあなたの呼び出しです。

コメント

  • 完全な453ページの文書は他にも潜在的な領域を示します。
    、ゴミのピックアップを民営化街をマージし、統合を含め、
    ウェイン郡の保健部門とでデトロイトの公立学校との提携
    レクリエーション。 提案はいずれも含まれていませんでした...

  • 取引に精通して人には、2つの側面は、まだマージされた会社の名前をハッシュしていると言いました。 しかし、この人は検討されているアイデアは、単語 "ドイツ"または頭字語中に "NYSE"を持っていない名前の選択であると述べた。 ...

  • 迷惑なうん、それは再帰的にマージされません。 私はbalphpライブラリに回避策を行うことができました。

分遅れで張るのコメント