Search code examples
perlyaml

Aliases resolved incorrectly in YAML modules?


I'm trying to load a "simple" YAML file using Perl:

foo: &baz
  dog: cat
  cat: rat
bar:
  <<: *baz
  rat: cheese

Using YAML, YAML::XS, or YAML::Syck I'm getting unexpected output from a test script:

{
  'foo' => {
    'cat' => 'rat',
    'dog' => 'cat'
  },
  'bar' => {
    'rat' => 'cheese',
    '<<' => $VAR1->{'foo'}
  }
}

In this case, {bar}->{dog} is undef. Running the same input through YAML Lint (or even Ruby's YAML module), it outputs as expected.

How can I get Perl to parse and output the correct format?


Solution

  • That YAML and YAML::Syck do not support the merge key language-independent type is logical, as these parsers implement YAML 1.0 and that extension was proposed for YAML 1.1.

    The extension is not part of the YAML 1.1 specification, and e.g. libyaml, on which YAML::XS is based, does not support it on its own. Ruby, Python and JavaScrip YAML parsers, implement the merge on top of the libyaml library, something that YAML::XS doesn't seem to do.

    As @bart commented, there are some workarounds by traversing the tree after loading: http://www.perlmonks.org/?node_id=813443