Слияние хэшей в YAML файлы конф

YAML очень удобно для записи файлов конфигурации. Основным преимуществом является то, что он читает, как текстовый файл. Это работает очень хорошо, если ваш файл конфигурации является плоским (нет иерархии) и не имеет повторений.
Если ваш файл конфигурации повторов, то имеет смысл выделить те элементы и использовать их. Я имею в виду это - скажем, у вас ваш конфигурационный файл выглядит следующим образом:

  развития:
   input_location: common_input
   output_location: dev_location
   почта:
     smtp_server: your_server
     Логин: ваш_логин
     пароль: top_secret
 производство:
   input_location: common_input
   output_location: dev_location
   почта:
     smtp_server: your_server
     Логин: ваш_логин
     пароль: top_secret 

Предполагая выше код в / TMP / test.yml вот как вы можете прочитать в питона и рубин
$cat readyml.py

 #! / USR / BIN / ENV питон
 pprint от импорта pprint как п.п.
 # В Debian необходимо установить Python-YAML
 YAML от импорта нагрузки, load_all, самосвалы
 хэш = нагрузки (открытой ('/ TMP / test.yml'))
 рр (хэш ['развитие']) 


$ cat readyml.rb

  #! / USR / BIN / ENV рубин
 требуют 'рр'
 хэш = YAML:: нагрузки (File.Open ('/ TMP / test.yml') для чтения.)
 п.п. хэш ['развитие'] 

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

Обратите внимание, что в приведенном выше фрагменте кода, все, кроме выходного лотка такой же, в части разработки и производства. Это где ут идентификатор узла доходит до спасения. Идея проста есть набор значений по умолчанию и переопределить их в другом месте.
Вы могли бы вытащить его на части следующим образом:

  по умолчанию: & умолчанию
   input_location: common_input
   output_location: dev_location
   почта:
     SENDER_NAME: адрес отправителя
     smtp_server: your_server
     Логин: ваш_логин
     пароль: top_secret
 развития:
   <<: * По умолчанию
 производство:
   <<: * По умолчанию
   output_location: prod_location 


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

Великий, он работает (тм)!.
Возможно мы обменяли некоторую ясность в немного магии. Вот небольшое объяснение: & * и <<: и который тега привязки может быть понята как идентификатор узла, * является узлом ссылки и <<: стенды для хэш-слияния.

Для получения дополнительной информации см. либо спецификации YAML или википедии
Пока все хорошо, но есть подвох, эти хэш сливается не рекурсивным. Что это означает следующее: допустим, вы хотите иметь другое имя отправителя для почты в двух средах, то может возникнуть соблазн сделать следующее:

  по умолчанию: & умолчанию
   input_location: common_input
   output_location: dev_location
   почта:
     SENDER_NAME: адрес отправителя
     smtp_server: your_server
     Логин: ваш_логин
     пароль: 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
   Логин: ваш_логин
   пароль: 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"
$

Вы сказали, у вас есть еще один уровень вложенности, а вы определенно можете развернуть еще один уровень, но затем она становится беспорядок. Итак, если вы не пытаетесь написать решение Башни Ханоя в конфигурационный файл, лучше restucture конфигурационный файл, чем копаться в YAML или нечто другое. Но это ваш звонок в любом случае.