Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Special key << not being honoured #86

Open
Altreus opened this issue Sep 19, 2018 · 4 comments
Open

Special key << not being honoured #86

Altreus opened this issue Sep 19, 2018 · 4 comments

Comments

@Altreus
Copy link

Altreus commented Sep 19, 2018

The << key in a YAML hash means merge.

http://yaml.org/refcard.html

Special keys:
'=' : Default "value" mapping key.
'<<' : Merge keys from another mapping.

This does not happen.

Reproducible example

firstmapping: &MAPPING
  akey: a value
  another-key:
    astructure:
       - a list 1
       - a list 2

secondmapping:
  <<: *MAPPING
  a-third-key: gets merged
➜ perl -MYAML::XS=LoadFile -MData::Dump -e'dd LoadFile("yaml.yml")'

Expected output

do {
  my $a = {
    firstmapping  => {
                       "akey" => "a value",
                       "another-key" => { astructure => ["a list 1", "a list 2"] },
                     },
    secondmapping => {
                       "akey" => "a value",
                       "another-key" => 'fix',
                       "a-third-key" => "gets merged"
                     },
  };
  $a->{"secondmapping"}{"another-key"} = $a->{"firstmapping"}{"another-key"};
  $a;
}

Observe that the only way to faithfully reproduce this is to copy the keys from the first mapping (but referencing the original values would be fine). I have only referenced the one that was already a ref since this seems like the most likely behaviour.

(I believe the fix syntax is just Data::Dump's way of preparing a structure to be self-referent. I borrowed it from the actual output below.)

Actual output

do {
  my $a = {
    firstmapping  => {
                       "akey" => "a value",
                       "another-key" => { astructure => ["a list 1", "a list 2"] },
                     },
    secondmapping => { "<<" => 'fix', "a-third-key" => "gets merged" },
  };
  $a->{secondmapping}{"<<"} = $a->{firstmapping};
  $a;
}

Observe that what actually happens is << is just a ref to the original thing. This strategy works for all keys except <<, which needs to be handled specially.

@perlpunk
Copy link
Collaborator

Yes, this << key is called a merge key: https://yaml.org/type/merge.html
It wasn't really made official, but I know that it is implemented in many other YAML processors.
It would be possible to implement it in YAML::XS, but I would first like to get @ingydotnet's ok before I start doing any work.
It won't be trivial to implement it, because a merge key has impact on the surrounding mapping, so it would be quite some work.

Meanwhile, if it's possible for you to use a module with a not yet stable API, you could try out YAML::PP::LibYAML which is a subclass of YAML::PP, and use the merge key feature like that: YAML::PP::Schema::Merge

@Altreus
Copy link
Author

Altreus commented Jun 4, 2019

Thanks, I didn't know about this alternative module :) I'm sure it will be fine to use for those cases when I particularly need that behaviour 👍

@rabbiveesh
Copy link

I see that this has been sitting around for a few years; is there any chance that an effort to do this will get revived?

@perlpunk
Copy link
Collaborator

I wouldn't expect anyone to work on this in the near future. I have many other tasks, and there is the mentioned YAML::PP::LibYAML alternative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants