Samenvoegen hashes in yaml conf-bestanden
YAML is heel handig voor het schrijven van configuratiebestanden. Belangrijkste voordeel is dat, het leest als tekstbestand. Dit werkt heel goed als je config bestand is plat (geen hiërarchie) en heeft geen herhalingen.
Als uw configuratie bestand herhalingen dan is het zinvol deze te scheiden van die elementen en ze opnieuw te gebruiken. Wat ik bedoel is dit - laten we zeggen dat je je config bestand ziet er als volgt uit:
ontwikkeling: input_location: common_input output_location: dev_location mail: smtp_server: uw_server login: your_login wachtwoord: top_secret productie: input_location: common_input output_location: dev_location mail: smtp_server: uw_server login: your_login wachtwoord: top_secret
Ervan uitgaande dat bovenstaande code in / tmp / test.yml hier is hoe je kunt lezen in Python en Ruby
$cat readyml.py
#! / Usr / bin / env python van pprint import pprint als pp # In debian moet python-yaml installeren van yaml import belasting, load_all, dump hash = belasting (open ("/ tmp / test.yml ')) pp (hash ['ontwikkeling'])
$ cat readyml.rb
#! / Usr / bin / env ruby require 'pp' hash = YAML:: load (File.open ('/ tmp / test.yml') te lezen.) pp hash ['ontwikkeling']
Hier is een handige one-liner voor Ruby versie
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' of u kunt hetzelfde proberen in irb of python console.
Merk op dat in het bovenstaande stukje code, alles is anders dan uitgang locatie is hetzelfde in ontwikkeling en productie deel. Dit is waar yml node identifier komt redden aan. Idee is simpel hebben een set van standaard waarden en ze op verschillende plaatsen te overschrijven.
Je zou kunnen trek het uit elkaar als volgt uit:
standaard: & defaults input_location: common_input output_location: dev_location mail: SENDER_NAME: afzender smtp_server: uw_server login: your_login wachtwoord: top_secret ontwikkeling: <<: * Defaults productie: <<: * Defaults output_location: prod_location
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Geweldig, het werkt (tm)!.
Ongetwijfeld hebben we wat meer duidelijkheid verhandeld voor een beetje magie. Hier is een kleine uitleg: &, * en <<: & dat is anker-tag kan worden opgevat als node identifier, * is knooppunt referentie en <<: staat voor hash samen te voegen.
Voor meer details zie ofwel yaml specs of wikipedia
Tot nu toe zo goed, maar er is een catch hier, deze hash samenvoegingen worden niet recursief. Wat het betekent is dit: laten we zeggen dat u verschillende afzender naam voor e-mail hebben in twee omgevingen, kunt u in de verleiding komen het volgende doen:
standaard: & defaults input_location: common_input output_location: dev_location mail: SENDER_NAME: afzender smtp_server: uw_server login: your_login wachtwoord: top_secret ontwikkeling: <<: * Defaults mail: SENDER_NAME: sender_dev productie: <<: * Defaults output_location: prod_location mail: SENDER_NAME: sender_prod
Laten controleren
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$
Oops, ging er iets mis, probleem zoals hierboven vermeld is dat de hash samen te voegen niet recursieve is en terwijl haar samenvoegen vervangen mail in gebreke per post van de productie die op een sleutel heeft. Oplossing / omzeilen is te rollen nog een niveau:
common_settings: & common_settings input_location: common_input output_location: dev_location mail_defaults: & mail_defaults SENDER_NAME: afzender smtp_server: uw_server login: your_login wachtwoord: top_secret standaard: & defaults <<: * Common_settings mail: <<: * Mail_defaults ontwikkeling: <<: * Defaults productie: <<: * Defaults mail: <<: * Mail_defaults SENDER_NAME: sender_prod
Laten we controleer opnieuw
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Hebt zeggen dat je je hebt nog een niveau van nesting, goed je kan zeker afrollen nog een niveau, maar dan wordt het een puinhoop. Dus, als je niet probeert om de oplossing te schrijven Torens van Hanoi in een conf bestand, is het beter om conf file restucture dan graven in yaml of iets anders. Maar dat is uw oproep toch.



































