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

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

  развитие:
   input_location: common_input
   output_location: dev_location
   мейл:
     smtp_server: your_server
     Login: your_login
     Парола: top_secret
 производство:
   input_location: common_input
   output_location: dev_location
   мейл:
     smtp_server: your_server
     Login: your_login
     Парола: top_secret 

Ако приемем, че по-горе код в / TMP / test.yml тук е как можете да прочетете в Python и Ruby
$cat readyml.py

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


$ cat readyml.rb

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

тук е удобна подложка за версия транслитерацията
$ 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
     Login: 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
     Login: 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
   Login: 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 или нещо друго. Но това е вашето обаждане, така или иначе.