有没有办法在YAML中对数组进行别名/锚定?

时间:2011-02-09 18:29:15

标签: ruby-on-rails yaml assets jammit

我正在使用Jammit为Rails应用程序打包资产,我有一些资产文件,我希望将其包含在少数几个组中。例如,我希望Sammy及其插件位于我的mobilescreen JS包中。

我试过这个:

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

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

和此:

mobile:
  - *SAMMY

但两者都将Sammy JS文件放在嵌套数组中,而Jammit无法理解。是否有将Array的元素直接包含在另一个Array中的语法?

NB :我意识到在这种情况下SAMMY数组中只有两个元素,所以每个都给每个元素一个别名和引用都不会太糟糕包。这种情况很好,但是当有五个或十个元素具有特定的加载顺序时,很快就无法维护。

6 个答案:

答案 0 :(得分:20)

我所知道的最近的解决方案就是这个:

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

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

或者,如已经建议的那样,将嵌套列表展平在代码段中。

注意:根据yaml-online-parser,您的第一个建议不是有效使用&lt;&lt; (用于合并两个词典中的键。然后锚点必须指向我相信的另一个词典。

答案 1 :(得分:16)

您的示例是有效的YAML(一个方便的检查位置是YPaste),但它没有定义合并的功能。根据{{​​3}},合并键可以具有值:

  1. 映射,在这种情况下,它会合并到父映射中。
  2. 映射序列,在这种情况下,每个映射都会逐个合并到父映射中。
  3. 无法合并序列。但是,您可以在代码中执行此操作。使用你的第二个想法中的YAML:

    mobile:
      - *SAMMY
    

    你会得到嵌套的序列 - 所以压扁它们!假设您有这种嵌套序列的映射:

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

    (当然,如果你有一个更复杂的YAML文件,并且你不希望每个序列变平(或者它们不是所有序列),你将不得不进行一些过滤。)

答案 2 :(得分:15)

如果您希望mobile等于sammy,您可以这样做:

mobile: *SAMMY

但是,如果您希望mobile除了sammy中的其他元素之外还包含其他元素,那么就我所知,在YAML中无法做到这一点。

答案 3 :(得分:0)

这可以解决您的问题:http://pastie.org/1790173

请注意,我必须在顶部创建空白default(或其他任何名称)组。

答案 4 :(得分:0)

正如有人建议的那样,当你需要压缩列表时,至少在ruby中,添加一个&#34;!flatten&#34;移动的类型说明符并实现一个扩展Array的类,添加yaml_tag并在init_with上展平编码器seq。

答案 5 :(得分:0)

此解决方案仅适用于 Symfony/PHP(其他语言的注意事项,见下文)

注意 PHP array manual page 中的数组键:

<块引用>

包含有效十进制整数的字符串,除非数字前面有一个 + 号,否则将被转换为 int 类型。例如。键“8”实际上将存储在 8 下。[...]

这意味着如果您实际上使用整数键索引锚点数组,则可以通过继续初始列表来简单地添加新键。所以你的解决方案看起来像这样:

sammy: &SAMMY
  1: public/javascripts/vendor/sammy.js
  2: public/javascripts/vendor/sammy*.js

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

您甚至可以覆盖键并添加新键:

laptop:
  <<: *SAMMY
  1: public/javascripts/sammy_laptop.js
  3: public/javascripts/something_else.js

在这两种情况下,最终结果都是一个完全有效的索引数组,就像以前一样。


其他编程语言

根据你的 YAML 实现你如何迭代你的数组,可以想象这也可以用在其他编程语言中。虽然有一个警告。

例如,在 JS 中,您也可以通过整数值访问数字字符串键:

const sammy = {"1": "public/javascripts/vendor/sammy.js"}

sammy["1"]; // "public/javascripts/vendor/sammy.js"
sammy[1]; // "public/javascripts/vendor/sammy.js"

但是您需要记住,您的初始数组现在是一个对象,并且您需要相应地对其进行迭代,例如:

Object.keys(sammy).forEach(key => console.log(sammy[key]))