Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

barbie (2653)

barbie
  reversethis-{ku. ... m} {ta} {eibrab}
http://barbie.missbarbell.co.uk/

Leader of Birmingham.pm [pm.org] and a CPAN author [cpan.org]. Co-organised YAPC::Europe in 2006 and the 2009 QA Hackathon, responsible for the YAPC Conference Surveys [yapc-surveys.org] and the QA Hackathon [qa-hackathon.org] websites. Also the current caretaker for the CPAN Testers websites and data stores.

If you really want to find out more, buy me a Guinness ;)

Links:
Memoirs of a Roadie [missbarbell.co.uk]
[pm.org]
CPAN Testers Reports [cpantesters.org]
YAPC Conference Surveys [yapc-surveys.org]
QA Hackathon [qa-hackathon.org]

Journal of barbie (2653)

Wednesday February 28, 2007
06:56 AM

YAML confusion with a List of Hashes

[ #32526 ]

The following is a snippet from a valid META.yml file:

   optional_features:
     - foo:
       description:        test
       requires_os:        Linux
       requires:
         Test::More:       0.47

and below is the snippet of data that both YAML::LoadFile() and YAML::Syck::LoadFile() return:

'optional_features' =>
  [
    {
      'foo'               => undef,
      'description'       => 'test',
      'requires_os'       => 'Linux',
      'requires'          => { 'Test::More' => '0.47' },
   }
  ],

Note that 'foo' is inside the hash, not the first item in the list. To me this is a design flaw, as it makes no sense to me having the list identifier as part of the hash. Plus it makes it painfully difficult to validate. I would have expected the following:

'optional_features' =>
  [
    'foo' => {
      'description'       => 'test',
      'requires_os'       => 'Linux',
      'requires'          => { 'Test::More' => '0.47' },
   }
  ],

Looking through the documents and bug reports I can't see anything that matches this, so I'm not sure whether I've misunderstood the specs or whether I have actually found a problem with the way YAML interprets this particular type of data structure. At the moment I don't have enough knowledge of YAML or YAML::Syck to understand how this is being parsed. Does anyone who knows them better than I, know whether this is a bug or expected behaviour?

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • The nesting of data structures in YAML blocks is indicated by indenting. So that:

    optional_features:
      - foo:
        description:        test
        requires_os:        Linux
        requires:
          Test::More:       0.47

    is just a tight version of

    optional_features:
      -
        foo:
        description:        test
        requires_os:        Linux

    • Yep, that is more what I was after. I'd misunderstood the bit about indenting, as I'd indented from the list, not the map key. A new version of Test-YAML-Meta coming soon :)

      Thanks.

    • You were almost there :-)

      Actually, you don't need the '-':

      #!env perl

      use strict;
      use strict;
      use warnings;

      use Data::Dumper;
      use YAML qw(Load);

      my $s = Load(<<EOF);
      ---
      optional_features:
        foo:
          description:        test
          requires_os:        Linux
          requires:
            Test::More:       0.47
        bar:
          description:        test

      EOF

      print Dumper $s;

      The result is

      --
      Igor Sutton
  • I think you have misunderstood the specs because you are getting the expected behaviour.

    You are interested in the value of the "optional_features" key, and you expect that to be a ref to a list of two elements: the first element is "foo"; the second is a ref to a hash of the other data.

    When you describe what you want you can see that the list has 2 elements. So in YAML you need one "-" for each element. So what you want is:

        optional_features:
            - foo
       
    • Actually, you need to *correct the indentation*.  (Why does this site screw with my indentation in plain text?  Yes, I should use "preview".  I'm now using "code")

      *This* is what you want:

      optional_features:
        - foo
        - description: test
          requires_os: Linux
          requires:
            Test::More: 0.47

      • Except it isn't ;)

        optional_features is a list, with each element of the list being a map with an identifier. The indentation I'd used made it look like the list element had no identifier, hence why 'foo => undef' existed inside the map, when I meant for it be the identifier for the map. ferreira [perl.org] has put me on the right track.

        As I suspected, I had just misunderstood the specs, as I didn't think I could have been the first person to come across this.

        As for indenting in use.perl, you want '<ecode>'

        • Are you sure it isn't what you want?  I'm trying to understand what you are describing.

          You say "each element of the list being a map with an identifier".  That is possible in Perl6, but in Perl5 a list (or array) element can only be a simple scalar or a reference to something.

          So I think you must mean that you want a list that looks something like this:  [ foo => { ... } ]

          Is that what you want?

          That list has 2 elements: the first is "foo"; the second is a hashref.

          In your initial post you sai