Slučování hashe v YAML conf soubory

31.července 2009 od Prashant · Komentáře
Soubor pod: technologie

YAML je velmi užitečná pro psaní konfiguračních souborů. Hlavní výhodou je to, že se čte jako textový soubor. To funguje opravdu dobře, pokud váš konfigurační soubor je plochá (bez hierarchie) a nemá žádné opakování.
Pokud váš soubor obsahuje opakování konfigurace, pak má smysl oddělit tyto prvky a je znovu použít. Co chci říct je to - řekněme, že jste si konfigurační soubor vypadá takto:

  vývoj:
   input_location: common_input
   output_location: dev_location
   mail:
     smtp_server: větev Váš_server
     Login: your_login
     heslo: top_secret
 produkce:
   input_location: common_input
   output_location: dev_location
   mail:
     smtp_server: větev Váš_server
     Login: your_login
     heslo: top_secret 

Za předpokladu, že výše uvedený kód do / tmp / test.yml zde je, jak si můžete přečíst v Python a Ruby
$cat readyml.py

 #! / Usr / bin / env python
 od dovozního pprint pprint jako pb
 # V Debianu je třeba nainstalovat python-YAML
 YAML z dovozu zatížení, load_all výklopné
 hash = zatížení (open ("/ tmp / test.yml '))
 pp (hash ['vývoj']) 


$ cat readyml.rb

  #! / Usr / bin / env ruby
 vyžadují "PP"
 hash = YAML :: load (File.open ("/ tmp / test.yml"). číst)
 pb hash ['vývoj'] 

tady je praktickým vložka verze ruby
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' , nebo si můžete zkusit totéž v IRB nebo python konzole.

Všimněte si, že ve výše uvedeném kódu, všechno je jiné, než výstup poloha je stejná ve vývoji a výrobě části. To je místo, kde yml uzel identifikátor přijde zachránit. Myšlenka je jednoduchá mít sadu výchozích hodnot a přepsat je na jiném místě.
Dalo by se vytáhněte ji od sebe takto:

  výchozí: výchozí nastavení a
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: odesílatel
     smtp_server: větev Váš_server
     Login: your_login
     heslo: top_secret
 vývoj:
   << * Výchozí
 produkce:
   << * Výchozí
   output_location: prod_location 


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

Skvělé, to funguje (tm)!.
Pravděpodobně se obchoduje nějakou přehlednost pro trochu magie. Zde je malé vysvětlení: a * a <<: a který je kotva tag lze chápat jako identifikátor uzlu, uzel * je referenční a <<: kandiduje na hash sloučení.

Pro více informací viz buď YAML specifikace nebo Wikipedie
Zatím je to dobré, ale je tu jeden háček, tyto mřížky se spojí nejsou rekurzivní. Co to znamená toto: řekněme, že chcete mít jiné jméno odesílatele pro poštu ve dvou prostředích, můžete být v pokušení udělat následující:

  výchozí: výchozí nastavení a
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: odesílatel
     smtp_server: větev Váš_server
     Login: your_login
     heslo: top_secret
 vývoj:
   << * Výchozí
   mail:
     SENDER_NAME: sender_dev
 produkce:
   << * Výchozí
   output_location: prod_location
   mail:
     SENDER_NAME: sender_prod 

Umožňuje kontrolovat

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

Jejda, něco se pokazilo, problém jak je uvedeno výše, je, že hash sloučení není rekurzivní a zatímco slučování nahradil mailu selhání poštou produkce, které má jen jeden klíč. Řešení / práce kolem je rozvinout ještě jednu úroveň:

  common_settings: & common_settings
 input_location: common_input
 output_location: dev_location
 mail_defaults: & mail_defaults
  SENDER_NAME: odesílatel
   smtp_server: větev Váš_server
   Login: your_login
   heslo: top_secret

 výchozí: výchozí nastavení a
   << * Common_settings
   mail:
     << * Mail_defaults
 vývoj:
   << * Výchozí
 produkce:
   << * Výchozí
   mail:
     << * Mail_defaults
     SENDER_NAME: sender_prod

Umožňuje kontrolovat znovu

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

Věděli jste, že máte ještě jednu úroveň vnoření, tak můžete určitě rozbalí jeden stupeň, ale pak se to stane nepořádek. Takže, pokud nejste se snaží psát řešení věže v Hanoji v conf souboru, je lepší restucture conf souboru, než kopat do YAML nebo něco jiného. Ale to je na vás tak jako tak.