web-dev-qa-db-fra.com

Un héritage plus complexe dans YAML?

YAML a l'héritage. L'exemple le plus clair que j'ai jamais vu est ici: http://blog.101ideas.cz/posts/dry-your-yaml-files.html

J'ai besoin de quelque chose de plus complexe: j'ai besoin de remplacer la propriété de l'objet de l'objet. Voici un exemple:

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

Je veux obtenir ce résultat:

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

Mais si vous déclarez comme ceci, vous obtiendrez ces propriétés incorrectes (selon les valeurs attendues):

foo_database.server.ip -> will be None
foo_database.user.name -> will be None

car le nouvel objet "serveur" n'a que la propriété "port" et il remplace tout l'ancien objet "serveur".

Comment puis-je obtenir le type d'héritage que je souhaite obtenir?

46
ceremcem

Malheureusement, vous ne pouvez pas obtenir le type d '"héritage" que vous souhaitez obtenir car l' "héritage" de YAML ressemble plus à une forme de "fusion de hachages".

Étendre votre configuration au moment où vous utilisez le *default alias, vous avez:

foo_database:
  server:
    ip: 192.168.1.5
    port: 2000
  db_name: test
  user: 
    name: root
    password: root

Si vous utilisez des hachages avec les mêmes touches par la suite, ils écraseront complètement les hachages déclarés plus tôt, vous laissant avec (excusez la mise en forme):

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

Donc, dans votre cas, il semblerait que puisque la configuration n'est pas exactement la même chose, le SECHAGE de votre configuration à l'aide d'ancres et d'alias n'est probablement pas le bonne approche.

Plus de références sur ce problème ci-dessous:

Modifier

Si vous le vouliez vraiment, je pense que vous pourriez reconfigurer votre YAML comme ci-dessous pour obtenir exactement ce que vous voulez, mais dans votre cas, je dirais que l'obscurcissement supplémentaire n'en vaut pas la peine:

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
33
Paul Fioravanti

Que dis-tu de ça? Utilisez plusieurs ancres.

database: &default
  server: &server
    ip: 192.168.1.5
    port: 2000
  db_name: test
  user: &user
    name: root
    password: root

foo_database:
  <<: *default
  server:
    << : *server
    port: 2001
  db_name: foo
  user:
    << : *user
    password: foo_root

C'est juste un peu de travail supplémentaire, et un peu plus difficile à lire que si ce que vous vouliez était intégré à YAML comme vous l'avez suggéré (je pensais que cela fonctionnerait aussi de cette façon). Mais globalement pas mal.

10
Tyler Collier