Mesclando hashes em conf yaml

31 de julho de 2009 por Prashant
Arquivado em: tecnologia

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 esses 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
     senha: top_secret
 produção:
   input_location: common_input
   output_location: dev_location
   mail:
     smtp_server: Your_Server
     login: your_login
     senha: top_secret 

Supondo que o 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 em pp
 # No debian precisa instalar python-yaml
 yaml de importação, despejo load_all carga,
 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)
 de hash pp ['desenvolvimento'] 

aqui é um forro de uma mão para a versão 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 do local de saída é a mesma no desenvolvimento e na parte de produção. Este é o lugar onde identificador do 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 e padrões:
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: remetente
     smtp_server: Your_Server
     login: your_login
     senha: top_secret
 desenvolvimento:
   <<: * Os padrões
 produção:
   <<: * Os padrões
   output_location: prod_location 


$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$

Grande, ele funciona (tm)!.
Provavelmente nós trocamos um pouco de clareza para um pouco de magia. Aqui está uma pequena explicação: &, * e <<: & que é marca de âncora pode ser entendida como identificador de nó, * é nó de referência e <<: representa a junção de hash.

Para mais detalhes veja tanto especificações yaml ou wikipedia
Até aí tudo bem, mas há um problema aqui, estas fusões de hash não são recursivas. O que isso 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 e padrões:
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: remetente
     smtp_server: Your_Server
     login: your_login
     senha: top_secret
 desenvolvimento:
   <<: * Os padrões
   mail:
     SENDER_NAME: sender_dev
 produção:
   <<: * Os padrões
   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
$

Opa, algo deu errado, como já mencionado problema é 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 / trabalho em torno é 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
   senha: top_secret

 padrões e padrões:
   <<: * Common_settings
   mail:
     <<: * Mail_defaults
 desenvolvimento:
   <<: * Os padrões
 produção:
   <<: * Os padrões
   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"
$

Será que você diz que tem um nível de aninhamento mais, bem, 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 conf, é melhor restucture arquivo conf de cavar yaml ou qualquer outra coisa. Mas isso é a chamada de qualquer maneira.

Comentários

  • O documento de 453 páginas cheio também lista de áreas potenciais para
    consolidação, incluindo a privatização coleta de lixo, a fusão da cidade e
    Wayne County departamentos de saúde e parcerias com escolas públicas em Detroit
    recreação. A proposta não inclui qualquer ...

  • Uma pessoa familiarizada com o negócio disse que os dois lados ainda estão hash um nome para uma empresa resultante da fusão. Mas esta pessoa disse uma idéia a ser considerado é a escolha de um nome que não tem a palavra "Deutsche" ou a sigla "NYSE" nele. ...

  • É chato não fundir recursivamente. Eu era capaz de fazer uma solução em minha biblioteca balphp.

comentários do blog powered by Disqus