Merging-Hashes in yaml conf-Dateien
YAML ist sehr nützlich für das Schreiben von Konfigurationsdateien. Primärer Vorteil ist, dass es wie Text-Datei liest. Dies funktioniert wirklich gut, wenn deine config-Datei ist flach (keine Hierarchie) und hat keine Wiederholungen.
Wenn Ihre Konfigurationsdatei hat Wiederholungen dann macht es Sinn zu trennen und diese Elemente wiederverwenden. Was ich meine ist diese - sagen wir mal du deine config-Datei wie folgt aussieht:
Entwicklung: input_location: common_input output_location: dev_location Mail: smtp_server: Ihr_Server Anmeldung: your_login Kennwort: top_secret Produktion: input_location: common_input output_location: dev_location Mail: smtp_server: Ihr_Server Anmeldung: your_login Kennwort: top_secret
Unter der Annahme obigen Code in / tmp / test.yml hier ist, wie Sie in Python und Ruby zu lesen
$cat readyml.py
#! / Usr / bin / env python von pprint Import pprint als PP # In Debian müssen python-yaml installieren von YAML Import Last, load_all, dump hash = load (open ('/ tmp / test.yml')) pp (Hash ['Entwicklung'])
$ cat readyml.rb
#! / Usr / bin / env ruby require 'pp' hash = YAML :: load (File.open ('/ tmp / test.yml'). lesen) PP-Hash ['Entwicklung']
hier ist ein handliches Einzeiler für Ruby-Version
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' oder Sie können die gleiche oder im IRB-Python-Konsole ausprobieren.
Beachten Sie, dass in dem obigen Code-Schnipsel, alles andere als Ausgang gleichen Standort in Entwicklung und Produktion ist ein Teil ist. Dies ist, wo yml Knotenkennung kommt zu retten. Idee ist einfach über einen Satz von Standardwerten zu überschreiben und sie an anderer Stelle.
Sie könnten auseinanderziehen wie folgt:
Standardwerte: Standardwerte & input_location: common_input output_location: dev_location Mail: sender_name: Absender smtp_server: Ihr_Server Anmeldung: your_login Kennwort: top_secret Entwicklung: <<: * Standardwerte Produktion: <<: * Standardwerte output_location: prod_location
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Große, funktioniert es (tm)!.
Wohl haben wir gehandelt etwas Klarheit für ein bisschen Magie. Hier eine kleine Erläuterung: &, * und <<: & das Anker-Tag ist als Knoten-Kennung verstanden werden kann, ist * Knoten-Referenz und <<: steht für Hash-Merge.
Weitere Details finden Sie entweder yaml specs oder wikipedia
So weit so gut, aber es gibt einen Haken hier, sind diese Hash-Zusammenführungen nicht rekursiv. Was es bedeutet, ist dies: Angenommen, Sie möchten unterschiedliche Absender-Namen für E-Mail in beiden Umgebungen haben, könnten Sie versucht, die Folgendes leistet:
Standardwerte: Standardwerte & input_location: common_input output_location: dev_location Mail: sender_name: Absender smtp_server: Ihr_Server Anmeldung: your_login Kennwort: top_secret Entwicklung: <<: * Standardwerte Mail: sender_name: sender_dev Produktion: <<: * Standardwerte output_location: prod_location Mail: sender_name: sender_prod
Lets prüfen
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$
Hoppla, etwas schief gelaufen ist, wie oben erwähnt Problem ist, dass die Hash-Merge nicht rekursiv ist und während der Zusammenführung es ersetzt Mail des Verzugs mit der Post der Produktion, die nur einen Schlüssel hat. Lösung / Workaround ist es, entrollen eine weitere Ebene:
common_settings: & common_settings input_location: common_input output_location: dev_location mail_defaults: & mail_defaults sender_name: Absender smtp_server: Ihr_Server Anmeldung: your_login Kennwort: top_secret Standardwerte: Standardwerte & <<: * Common_settings Mail: <<: * Mail_defaults Entwicklung: <<: * Standardwerte Produktion: <<: * Standardwerte Mail: <<: * Mail_defaults sender_name: sender_prod
Lets erneut prüfen
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Wussten Sie sagen, Sie haben noch eine weitere Ebene der Verschachtelung, gut man kann definitiv entrollen ein weiteres Level, aber dann wird es ein Durcheinander. Also, wenn Sie nicht versuchen, Lösung für Türme von Hanoi in einer conf-Datei zu schreiben, ist es besser, conf-Datei als Graben in yaml oder etwas anderes restucture. Aber das ist Ihr Anruf trotzdem.



































