在YAML conf文件合并哈希

2009年7月31日, prashant
提起下: 技术

YAML是相当方便的编写配置文件。 主要优点是,它像文本文件中读取。 这个作品真的很好,如果你的配置文件是平坦的(不分层),并没有重复。
如果您的配置文件中有重复,然后分离出这些元素和重用它们是有意义的。 我的意思是 - 让我们说你的配置文件看起来像这样:

 发展:
   input_location:common_input
   output_location:dev_location
  邮箱:
     smtp_server:您的服务器
    登录:your_login
    密码:top_secret
生产:
   input_location:common_input
   output_location:dev_location
  邮箱:
     smtp_server:您的服务器
    登录:your_login
    密码:top_secret 

假设上面的代码在/ tmp / test.yml这里你可以看到如何在Python和Ruby
$cat readyml.py

 #!的/ usr / bin中/ env的蟒蛇
从pprint为PP进口pprint
 #Debian中需要安装python-YAML
从的YAML进口负载,load_all,转储
哈希=负载(开放(“/ TMP / test.yml的”))
 PP(哈希['发展']) 


$ cat readyml.rb

  #!/ USR / BIN / env的红宝石
需要“PP”
哈希= YAML的::负载(的File.Open(“/ TMP / test.yml的”)。)
 PP哈希['发展'] 

这里是一个方便的Ruby版本的班轮
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]'或者你可以尝试在irb或Python控制台相同。

请注意,在上面的代码片断,一切都以外的输出位置是相同的开发和生产的一部分。 这是YML节点标识符来抢救。 想法很简单,有一组默认值和重写他们在不同的地方。
你可以把它拆开如下:

 默认:与默认
   input_location:common_input
   output_location:dev_location
  邮箱:
     SENDER_NAME:发送方
     smtp_server:您的服务器
    登录:your_login
    密码:top_secret
发展:
   <<:*默认
生产:
   <<:*默认
   output_location:prod_location 


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

伟大的,它的工作原理(TM)。
可以说,我们交易有点像魔术,一些清晰度。 这里是一个小说明:&,*和<<: - 这是锚标记,可以理解为节点标识符,*是节点的参考和<<:哈希合并。

详细内容见或者YAML规格维基
到目前为止,那么好,但有一个陷阱,在这里,这些哈希合并不是递归的。 它的意思是这样的:让我们说你要在两个环境不同的邮件发送者的名字,你可能会受到诱惑,做到以下几点:

 默认:与默认
   input_location:common_input
   output_location:dev_location
  邮箱:
     SENDER_NAME:发送方
     smtp_server:您的服务器
    登录:your_login
    密码:top_secret
发展:
   <<:*默认
  邮箱:
     SENDER_NAME:sender_dev
生产:
   <<:*默认
   output_location:prod_location
  邮箱:
     SENDER_NAME:sender_prod 

让检查

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

哎呀,出事了,上述问题是不是递归哈希合并,合并时,它取代默认的邮件,邮件只有一个关键的生产。 展开多层次的解决方案/工作大约是:

  common_settings:&common_settings
 input_location:common_input
 output_location:dev_location
 mail_defaults:&mail_defaults
  SENDER_NAME:发送方
   smtp_server:您的服务器
  登录:your_login
  密码:top_secret

默认:与默认
   <<:* common_settings
  邮箱:
     <<:* mail_defaults
发展:
   <<:*默认
生产:
   <<:*默认
  邮箱:
     <<:* mail_defaults
     SENDER_NAME:sender_prod

让我们再次检查

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

你说你多了一个嵌套级别,你绝对可以展开一个级别,但后来它变成一个烂摊子。 所以,如果你不尝试写河内塔在conf文件的解决方案,它是更好地挖成YAML或别的东西restucture比conf文件。 但是,这是你的电话了。

评论

  • 完整的453页的文件还列出了潜在的领域
    整合,包括私有化的拾垃圾,合并的城市和
    韦恩县卫生部门和底特律公立学校合作
    娱乐。 该提案没有包括任何...

  • 熟悉交易的人士说,双方仍然哈希为合并后的公司名称。 但这位人士说,正在考虑的一个思路,就是选择一个名字,没有单词“德意志”或“纽约证券交易所”的缩写,。 ...

  • 是恼人的,它不合并递归。 我是能够使我balphp图书馆的一种变通方法。

博客评论由Disqus