Fletning hashes i yaml conf filer
YAML er ganske praktisk for at skrive konfigurationsfiler. Primære fordel er, at det lyder som tekstfil. Dette fungerer rigtig godt, hvis din config fil er flad (ingen hierarki) og har ingen gentagelser.
Hvis din konfigurationer fil har gentagelser så giver det mening at adskille de elementer og genbruge dem. Hvad jeg mener er dette - lad os sige, du din config fil ser sådan her ud:
udvikling: input_location: common_input output_location: dev_location mail: smtp_server: din_server login: your_login Password: top_secret produktion: input_location: common_input output_location: dev_location mail: smtp_server: din_server login: your_login Password: top_secret
Under forudsætning af ovenstående kode i / tmp / test.yml her er, hvordan du kan læse i Python og Ruby
$cat readyml.py
#! / Usr / bin / env python fra pprint import pprint som pp # I debian skal installere python-yaml fra yaml import belastning, load_all, dump hash = belastning (open ("/ tmp / test.yml ')) pp (hash ['udvikling'])
$ cat readyml.rb
#! / Usr / bin / env ruby kræver 'PP' hash = YAML:: load (File.open ('/ tmp / test.yml') læst.) pp hash ['udvikling']
her er en handy en liner til Ruby-version
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' , eller du kan prøve det samme i IRB-eller Python konsollen.
Bemærk, at i ovenstående kodestykke, alt er andre end produktionen placering er ens i udvikling og produktion del. Det er her yml node identifikator kommer til undsætning. Ideen er enkel have et sæt af standardværdier og tilsidesætte dem på andet sted.
Du kan trække det fra hinanden som følger:
standardindstillingerne: & defaults input_location: common_input output_location: dev_location mail: SENDER_NAME: afsender smtp_server: din_server login: your_login Password: top_secret udvikling: <<: * Defaults produktion: <<: * Defaults output_location: prod_location
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Fantastisk, det virker (tm)!.
Formentlig har vi handlet nogle klarhed for lidt magi. Her er en lille forklaring: &, * og <<: & som er ankerkode kan forstås som node identifikator, * er node reference og <<: står for hash fusionere.
For flere detaljer se enten yaml specs eller wikipedia
Så langt så godt men der er en fangst her, disse hash fusionerer er ikke rekursive. Hvad det betyder er dette: Lad os sige du vil have forskellige afsenderens navn for e-mails i to miljøer, kan du blive fristet til at gøre følgende:
standardindstillingerne: & defaults input_location: common_input output_location: dev_location mail: SENDER_NAME: afsender smtp_server: din_server login: your_login Password: top_secret udvikling: <<: * Defaults mail: SENDER_NAME: sender_dev produktion: <<: * Defaults output_location: prod_location mail: SENDER_NAME: sender_prod
Lad os kontrollere
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$
Ups, noget gik galt, problemet som nævnt ovenfor er, at hash fletningen ikke er rekursive, og samtidig at lægge det sammen erstattet post af misligholdelse fra mail den produktion, som kun har en nøgle. Løsning / arbejde omkring er at oprulle endnu et niveau:
common_settings: & common_settings input_location: common_input output_location: dev_location mail_defaults: & mail_defaults SENDER_NAME: afsender smtp_server: din_server login: your_login Password: top_secret standardindstillingerne: & defaults <<: * Common_settings mail: <<: * Mail_defaults udvikling: <<: * Defaults produktion: <<: * Defaults mail: <<: * Mail_defaults SENDER_NAME: sender_prod
Lets check igen
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Vidste du siger du har en mere lige af nesting, godt du kan helt sikkert oprulle en mere lige, men så bliver det noget rod. Så hvis du ikke forsøger at skrive løsningen på tårnene i Hanoi i en conf-fil, er det bedre at restucture conf fil end at grave i yaml eller noget andet. Men det er dit opkald alligevel.



































