airr airr - 15 days ago 6
YAML Question

Accessing data in perl after loading yaml file

I have to parse an yaml and process the data in perl.

my yaml file looks like this:

route1:
dst:
- atl
src:
- bos
route2:
dst:
- sfo
src:
- dal


My parsing script looks like this:

use strict;
use warnings;
use YAML;
use Data::Dumper;

open my $fh, '<', 'testcase'
or die "can't open file';

my(@routes) = YAML::LoadFile($fh);
print Dumper(@routes), "\n";


The output of this looks as I expect

$VAR1 = {
'route2' => {
'src' => [
'dal'
],
'dst' => [
'sfo'
]
},
'route1' => {
'src' => [
'bos'
],
'dst' => [
'atl'
]
}
};


If I understand correctly @routes is an array.
Each element (route1, route2) of this array is an hash.
Each element of this hash is a hash.
And each element of this hash is an array.

Array of hash of hash of array.

How do I loop through to get the elements of @routes. If I loop through @routes, I should be getting route1 and route2. In the real case, I wont know how many "route" are in my array @routes.

Answer

@routes is an array. It contains one element, which is a reference to a hash. This hash has two keys (route1, route2), and each associated value is another reference to a hash. The inner hashes also have two keys each (src, dst). The associated values are references to arrays, each of which have one element, which is a string.

You don't see the outer array structure in your dump because you effectively passed a list of the contents of @routes to Dumper, not the array itself. And the array only has one element, so it is as if you did Dumper($routes[0]).

The following code is untested but may work:

use strict;
use warnings;
use YAML qw(LoadFile);

my $routes = LoadFile('testcase');
my $n = keys %{$routes};
print "There are $n routes\n";

for my $k1 (keys %{$routes}) {
    print "$k1 =>\n";
    for my $k2 (keys %{$routes->{$k1}}) {
        print "    $k2 => @{$routes->{$k1}{$k2}}\n";
    }
}