YAML 中更复杂的继承? [英] More complex inheritance in YAML?

查看:17
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆