Hashes fusão em arquivos de conf yaml
YAML é bastante útil para gravação de arquivos de configuração. Principal vantagem é que, lê-se como arquivo de texto. Isso funciona muito bem se o seu arquivo de configuração é plana (sem hierarquia) e não tem repetições.
Se o seu arquivo de configurações tem repetições então faz sentido para separar os elementos e reutilizá-los. O que quero dizer é isso - vamos dizer que você seu arquivo de configuração parecida com esta:
desenvolvimento: input_location: common_input output_location: dev_location mail: smtp_server: Your_Server login: your_login password: top_secret produção: input_location: common_input output_location: dev_location mail: smtp_server: Your_Server login: your_login password: top_secret
Assumindo código acima em / tmp / test.yml aqui está como você pode ler em python e ruby
$cat readyml.py
#! / Usr / bin / env python de pprint pprint importação pp # No debian precisa instalar python-yaml yaml de carga de importação, load_all, despejo hash = carga (open ('/ tmp / test.yml')) pp (hash ['desenvolvimento'])
$ cat readyml.rb
#! / Usr / bin / env ruby require 'pp' hash = YAML:: load (File.open ('/ tmp / test.yml') ler.) pp hash ['desenvolvimento']
aqui é um forro de uma versão acessível para ruby
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' ou você pode tentar o mesmo em irb ou console python.
Note-se que no trecho de código acima, tudo é diferente de local de saída é o mesmo, em parte, desenvolvimento e produção. Este é o lugar onde identificador de nó yml vem resgatar. Idéia é simples ter um conjunto de valores padrão e substituí-los em lugar diferente.
Você pode puxá-lo para além da seguinte forma:
padrões: padrões & input_location: common_input output_location: dev_location mail: sender_name: remetente smtp_server: Your_Server login: your_login password: top_secret desenvolvimento: <<: * Defaults produção: <<: * Defaults output_location: prod_location
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Grande, ele funciona (tm)!.
Indiscutivelmente nós trocamos um pouco de clareza para um pouco de magia. Aqui está uma pequena explicação: &, * e <<: & que é tag de âncora pode ser entendida como identificador de nó, * é referência nó e <<: stands para fundir hash.
Para mais detalhes veja ou especificações yaml ou wikipedia
Até aqui tudo bem, mas há um problema aqui, essas fusões não são de hash recursiva. O que significa é o seguinte: digamos que você quer ter nome de remetente diferente para o correio em dois ambientes, você pode ser tentado a fazer o seguinte:
padrões: padrões & input_location: common_input output_location: dev_location mail: sender_name: remetente smtp_server: Your_Server login: your_login password: top_secret desenvolvimento: <<: * Defaults mail: sender_name: sender_dev produção: <<: * Defaults output_location: prod_location mail: sender_name: sender_prod
Vamos verificar
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$
Oops, algo deu errado, problema, como mencionado acima é que a junção de hash não é recursivo e enquanto fundindo-substituído e-mail de incumprimento por e-mail da produção que tem apenas uma chave. Solução / solução é para desenrolar mais um nível:
common_settings: & common_settings input_location: common_input output_location: dev_location mail_defaults: & mail_defaults sender_name: remetente smtp_server: Your_Server login: your_login password: top_secret padrões: padrões & <<: * Common_settings mail: <<: * Mail_defaults desenvolvimento: <<: * Defaults produção: <<: * Defaults mail: <<: * Mail_defaults sender_name: sender_prod
Vamos verificar novamente
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$
Você disse que você tem mais um nível de aninhamento, assim você pode definitivamente desenrolar mais um nível, mas depois torna-se uma bagunça. Então, se você não está tentando escrever solução para torres de Hanói em um arquivo de conf, é melhor restucture arquivo conf de cavar yaml ou outra coisa. Mas isso é a chamada de qualquer maneira.



































