在YAML conf文件合并哈希
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文件的解决方案,它是更好地restucture conf文件,比挖成YAML或别的东西。 但是,这无论如何是您的通话。



































