Scalanie hashe w YAML plików conf
YAML jest bardzo przydatny do pisania plików konfiguracyjnych. Podstawową zaletą jest to, że czyta się ją jak plik tekstowy. To działa bardzo dobrze, jeśli plik konfiguracyjny jest płaska (bez hierarchii) i nie ma powtórzeń.
Jeśli plik konfiguracji ma powtórzeń to ma sens wyodrębnienie tych elementów i ponowne ich wykorzystanie. Chodzi mi o to - powiedzmy, że twój plik konfiguracyjny wygląda tak:
rozwój: input_location: common_input output_location: dev_location mail: smtp_server: adres_IP_serwera login: your_login hasło: top_secret produkcja: input_location: common_input output_location: dev_location mail: smtp_server: adres_IP_serwera login: your_login hasło: top_secret
Zakładając powyższy kod w / tmp / test.yml Oto jak można przeczytać w Python i Ruby
$cat readyml.py
#! / Usr / bin / env python z pprint pprint importu jak PP # W Debianie trzeba zainstalować python-YAML od obciążenia YAML importu, load_all, zrzuć hash = obciążenie (open ("/ tmp / test.yml ')) pp (hash ['rozwój'])
$ cat readyml.rb
#! / Usr / bin / env ruby wymagają "PP" hash = YAML :: load (File.open ("/ tmp / test.yml"). czytać) hash pp ['rozwój']
tu jest ciekawa liner wersji ruby
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' lub możesz spróbować sam w IRB lub konsoli Pythona.
Zauważ, że w powyższym fragmencie kodu, wszystko jest inne niż miejsce wyjścia jest taki sam w rozwoju, a część produkcji. To gdzie yml identyfikator węzła przychodzi na ratunek. Pomysł jest prosty posiada zbiór wartości domyślnych i zastąpić je w innym miejscu.
Możesz rozebrać się następująco:
Domyślnie: i domyślnie input_location: common_input output_location: dev_location mail: sender_name: nadawca smtp_server: adres_IP_serwera login: your_login hasło: top_secret rozwój: << Pytanie: * defaults produkcja: << Pytanie: * defaults output_location: prod_location
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Świetnie, to działa (tm)!.
Prawdopodobnie mamy notowane na przejrzystości na odrobinę magii. Oto małe wyjaśnienie: &, * i <<: & który jest tag kotwica może być rozumiana jako identyfikator węzła, * jest węzeł odniesienia i <<: oznacza hash korespondencji seryjnej.
Więcej szczegółów można znaleźć zarówno YAML specyfikacje lub Wikipedii
Jak na razie dobrze, ale jest pewien haczyk tutaj te hash łączy nie są rekurencyjne. Co to znaczy jest to, powiedzmy, że chcesz mieć inną nazwę nadawcy poczty w dwóch środowiskach, może ulec pokusie, aby wykonać następujące czynności:
Domyślnie: i domyślnie input_location: common_input output_location: dev_location mail: sender_name: nadawca smtp_server: adres_IP_serwera login: your_login hasło: top_secret rozwój: << Pytanie: * defaults mail: sender_name: sender_dev produkcja: << Pytanie: * defaults output_location: prod_location mail: sender_name: sender_prod
Pozwala sprawdzić
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$
Niestety, coś poszło nie tak, problem jak wspomniano powyżej jest to, że hash merge nie jest rekurencyjne i podczas łączenia go zastąpić pocztę niedotrzymania przez elektroniczną produkcji, która ma tylko jeden klucz. Rozwiązanie / praca wokół jest rozwinąć jeszcze jeden poziom:
common_settings: & common_settings input_location: common_input output_location: dev_location mail_defaults: zewnętrzne i mail_defaults sender_name: nadawca smtp_server: adres_IP_serwera login: your_login hasło: top_secret Domyślnie: i domyślnie << Pytanie: * common_settings mail: << Pytanie: * mail_defaults rozwój: << Pytanie: * defaults produkcja: << Pytanie: * defaults mail: << Pytanie: * mail_defaults sender_name: sender_prod
Sprawdźmy jeszcze raz
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Czy mówisz, że masz jeden więcej poziom zagnieżdżenia, dobrze można z pewnością rozwinąć jeszcze jeden poziom, ale to staje się bałagan. Tak więc, jeśli nie próbujesz napisać rozwiązanie Wieże Hanoi w conf pliku, to lepiej restucture conf plik niż kopanie w YAML lub coś innego. Ale to jest rozmowa tak.
Komentarze
- Dogging
- sřgemaskineoptimering
- Benjamin "balupton" Lupton



































