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ハッシュ['開発'] 

ここにルビーバージョンのための便利な一行は、
$ 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を
これまでのところは良いですがキャッチはここにある、これらのハッシュのマージは再帰的ではありません。 それは何を意味することはこれです:たとえば、あなたは二つの環境でメール用の別の送信者の名前を持つよ​​うにしたいと言う、あなたは次のことを行うように誘惑されることがあります。

 デフォルト値:&デフォルト
   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することをお勧めします。 しかし、それはとにかくあなたの呼び出しです。