YAML 中更复杂的继承? [英] More complex inheritance in YAML?
问题描述
YAML 具有继承性.我见过的最清晰的例子在这里:http://blog.101ideas.cz/posts/dry-your-yaml-files.html
YAML has inheritance. The most clear example I have ever seen is here: http://blog.101ideas.cz/posts/dry-your-yaml-files.html
我需要更复杂的东西:我需要覆盖对象的对象属性.这是一个例子:
I need something more complex: I need to override object's object's property. Here is an example:
database: &default
server:
ip: 192.168.1.5
port: 2000
db_name: test
user:
name: root
password: root
# database foo differs from default by only its port and user password
foo_database:
<<: *default
server:
port: 2001
db_name: foo
user:
password: foo_root
我想得到这个结果:
foo_database.server.ip -> 192.168.1.5
foo_database.server.port -> 2001
foo_database.db_name -> foo
foo_database.user.name -> root
foo_database.user.password -> foo_root
但是如果你这样声明,你会得到这些属性不正确(根据预期值):
But if you declare like this, you will get these properties incorrect (according to expected values):
foo_database.server.ip -> will be None
foo_database.user.name -> will be None
因为新的服务器"对象只有端口"属性,它会覆盖整个旧的服务器"对象.
because new "server" object has only "port" property and it overrides whole old "server" object.
如何获得我想要实现的那种继承?
How do I get the kind of inheritance which I want to achieve?
这是我在 LiveScript:
config =
default:
ip: 192.168.1.5
port: 2000
name:
oot
password:
oot
db:
name: default
location: LA
foo-database:~ -> @default `merge` do
ip: 11.11.11.11
db:
name: my-foo
bar-database:~ -> @foo-database `merge` do
password: 1234
db:
location: SF
config.default
# => {"ip":"192.168.1.5","port":2000,"name":"root","password":"root","db":{"name":"default","location":"LA"}}
config.foo-database
# => {"ip":"11.11.11.11","port":2000,"name":"root","password":"root","db":{"name":"my-foo","location":"LA"}}
config.bar-database
# => {"ip":"11.11.11.11","port":2000,"name":"root","password":"1234","db":{"name":"my-foo","location":"SF"}}
推荐答案
很遗憾,你无法得到你想要实现的那种继承",因为 YAML 的继承"更像是一种合并哈希"的形式.
Unfortunately, you can't get the kind of "inheritance" you want to achieve because YAML's "inheritance" is more like a form of "merging hashes".
在您使用 *default
别名时扩展您的配置,您有:
Expanding out your configuration at the point you use the *default
alias, you have:
foo_database:
server:
ip: 192.168.1.5
port: 2000
db_name: test
user:
name: root
password: root
如果您之后使用具有相同键的散列,它们将完全覆盖之前声明的散列,留下(请原谅格式化):
If you use hashes with the same keys afterwards, they will completely overwrite the hashes declared earlier, leaving you with (excuse the formatting):
foo_database:
<罢工>
server:
ip: 192.168.1.5
port: 2000
db_name: test
user:
name: root
password: root
server:
port: 2001
db_name: foo
user:
password: foo_root
因此,在您的情况下,似乎由于配置不完全相同,使用锚点和别名干燥您的配置可能不是正确的方法.
So, in your case, it would seem that since the config is not exactly the same, DRYing up your configuration using anchors and aliases probably isn't the right approach.
关于这个问题的更多参考如下:
More references on this issue below:
如果你真的想要,我认为你可以重新配置你的 YAML 以获得你想要的,但在你的情况下,我会说额外的混淆是不值得的:
If you really wanted to, I think you could reconfigure your YAML as below to get exactly what you want, but in your case, I would say the extra obfuscation isn't worth it:
server_defaults: &server_defaults
ip: 192.168.1.5
port: 2000
user_defaults: &user_defaults
name: root
password: root
database: &default
server:
<<: *server_defaults
db_name: test
user:
<<: *user_defaults
foo_database:
<<: *default
server:
<<: *server_defaults
port: 2001
db_name: foo
user:
<<: *user_defaults
password: foo_root
这篇关于YAML 中更复杂的继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!