Scalanie hashe w YAML plików conf

31 lipca 2009 przez Prashant
Opublikowane jako: technologii

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

  • Pełny 453-stronicowy dokument wymienia także potencjalne obszary dla
    konsolidacji, w tym prywatyzacji odbiór śmieci, łączących miasto i
    Wayne County wydziały zdrowia i partnerstwie z Detroit szkołach publicznych na
    rekreacji. Wniosek nie zawiera żadnych ...

  • Osoba znana z transakcji powiedział, że obie strony nadal są mieszania się nazwy dla połączonej firmy. Ale ta osoba powiedziała pomysł rozważana jest wybór nazwy, która nie ma słowa "Deutsche" lub skrót "NYSE" w nim. ...

  • Tak irytujące nie łączyć rekurencyjnie. Udało mi się zrobić obejście w mojej balphp biblioteki.

komentarze w blogu zasilane Disqus