Злиття хешей в 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 / бен / ENV пітон
 pprint від імпорту pprint як пп
 # В Debian необхідно встановити Python-YAML
 YAML від імпорту навантаження, load_all, самоскиди
 хеш = навантаження (відкритою ('/ TMP / test.yml))
 рр (хеш ['розвиток']) 


$ cat readyml.rb

  #! / USR / бен / ENV рубін
 require 'рр'
 хеш = 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 або щось інше. Але це ваш дзвінок в будь-якому випадку.