Сливане на хешове в yaml файлове CONF

YAML е доста удобна за писане на конфигурационни файлове. Основното предимство е, че се чете като текстов файл. Това работи много добре, ако ви конфигурационния файл е плоска (без йерархия) и все още няма повторения.
Ако вашият файл с конфигурации повторения тогава има смисъл да се отделят тези елементи и да ги използва повторно. Това, което искам да кажа е - нека кажем, че ти конфигурационния файл изглежда така:

  развитие:
   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 тук е как можете да прочетете в питон и рубини
$cat readyml.py

 #! / ЮЕсАр / хамбар / "Околна среда" питон
 от вносни pprint pprint като п
 # В Дебиан трябва да инсталирате Python-yaml
 от внос yaml натоварване, load_all, самосвали
 хеш = натоварване (Open ("/ TMP / test.yml"))
 п.п. (хеш ["разработване"]) 


$ cat readyml.rb

  #! / ЮЕсАр / хамбар / "Околна среда" рубин
 изисква "ПП"
 хеш = YAML: натоварване (File.open ("/ TMP / test.yml") чете.)
 п.п. хеш ["разработване"] 

тук е удобна подложка за рубин версия
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' или можете да опитате същото в IRB или питон конзола.

Имайте предвид, че в горния фрагмент код, всичко е, различни от изходната Мястото е същото в разработването и производството част. Това е мястото, където 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 характеристики или Уикипедия
Дотук добре, но има уловка тук, тези хеш слива не са рекурсивни. Какво означава това: Да речем, че искате да имат различни името на подателя за поща в две среди, може да се изкушите да направите следното:

  подразбиране: и по подразбиране
   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
$

Опа, нещо се е объркало, проблем, както беше споменато по-горе е, че хеш сливат не е рекурсивен и при обединяването на замени поща на неизпълнение на задълженията по пощата на продукция, която има само един ключ. Решение / работа около, за да се развивам още едно ниво:

  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 файл, той е по-добре да restucture CONF файл, отколкото да копаят в yaml или нещо друго. Но това е вашето обаждане или иначе.