web-dev-qa-db-fra.com

Existe-t-il un moyen d'alias/ancrer un tableau dans YAML?

J'utilise Jammit pour regrouper les éléments d'actif pour une application Rails. J'ai quelques fichiers d'actif que j'aimerais être inclus dans chacun des groupes. Par exemple, j'aimerais que Sammy et ses plugins soient à la fois dans mes packages mobile et screen JS.

J'ai essayé ceci:

sammy: &SAMMY
  - public/javascripts/vendor/sammy.js
  - public/javascripts/vendor/sammy*.js

mobile:
  <<: *SAMMY
  - public/javascripts/something_else.js

et ça:

mobile:
  - *SAMMY

mais tous deux placent les fichiers Sammy JS dans un tableau imbriqué, ce que Jammit ne peut pas comprendre. Existe-t-il une syntaxe pour inclure les éléments d'un tableau directement dans un autre tableau?

NB: Je me rends compte que dans ce cas, il n'y a que deux éléments dans le tableau SAMMY, il ne serait donc pas mauvais de donner à chacun un alias et une référence dans chaque paquet. C'est bien dans ce cas, mais cela devient vite intolérable quand cinq ou dix éléments ont un ordre de chargement spécifique.

29
James A. Rosen

Votre exemple est valide YAML (un emplacement pratique à vérifier est YPaste ), mais le résultat de la fusion n’est pas défini. Selon le spec , une clé de fusion peut avoir une valeur:

  1. Un mappage, auquel cas il est fusionné dans le mappage parent.
  2. Une séquence de mappages, auquel cas chacun est fusionné un par un avec le mappage parent.

Il n'y a aucun moyen de fusionner des séquences. Vous pouvez cependant le faire dans le code. En utilisant le YAML de votre deuxième idée:

mobile:
  - *SAMMY

vous obtiendrez des séquences imbriquées - alors aplatissez-les! En supposant que vous ayez une cartographie de telles séquences imbriquées:

data = YAML::load(File.open('test.yaml'))
data.each_pair { |key, value| value.flatten! }

(Bien sûr, si vous avez un fichier YAML plus compliqué et que vous ne voulez pas que chaque séquence soit aplatie (ou ce ne sont pas toutes des séquences), vous devrez faire un filtrage.)

16
Jesse Beder

La solution la plus proche que je connaisse est celle-ci:

sammy:
  - &SAMMY1
    public/javascripts/vendor/sammy.js
  - &SAMMY2
    public/javascripts/vendor/sammy*.js

mobile:
  - *SAMMY1
  - *SAMMY2
  - public/javascripts/something_else.js

Alternativement, comme déjà suggéré, aplatissez les listes imbriquées dans un extrait de code.

Note: selon yaml-online-parser , votre première suggestion n’est pas une utilisation valide de << (utilisé pour fusionner les clés de deux dictionnaires. L’ancre doit alors pointer vers un autre dictionnaire, je crois.

18
yngve

Si vous voulez que mobile soit égal à sammy, vous pouvez simplement faire:

mobile: *SAMMY

Cependant, si vous voulez que mobile contienne d'autres éléments en plus de ceux de sammy, il n'y a aucun moyen de le faire dans YAML, à ma connaissance.

14
sepp2k

cela devrait résoudre votre problème: http://pastie.org/1790173 .

Notez que je devais créer un groupe vierge default (ou le nom de votre choix) en haut.

1
Wojtek Mach

Comme il a été suggéré, lorsque vous avez besoin d'aplatir une liste, du moins en Ruby, il est trivial d'ajouter un spécificateur de type "! Flatten" à mobile et d'implémenter une classe qui étend Array, ajoute le yaml_tag et aplatit le codeur seq on init_with.

0
Eric Woodruff