Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I walk a YAML tree with Perl's YAML::Tiny?

Tags:

yaml

perl

I have a YAML document like this:

---
version: 1
rootdirectory:
  - subdirectory:
    - file1
    - file2
  - subdirectory2

that I am loading into a YAML::Tiny object like this:

$configuration = YAML::Tiny->read($configuration_file)

I see from invoking the script with the Perl debugger that what I end up with is a set of nested hashes and arrays that reflect the structure of the YAML source:

0  YAML::Tiny=ARRAY(0x84e3ba4)
   0  HASH(0x80627dc)
      'rootdirectory' => ARRAY(0x84e3d3c)
         0  HASH(0x84352b0)
            'subdirectory' => ARRAY(0x84e3df0)
               0  'file1'
               1  'file2'
         1  'subdirectory2'
      'version' => 1

So, I can do things like the following without problem:

print $configuration->[0]->{version}

and receive the expected answer of '1'. Likewise, I can also do:

print $configuration->[0]->{rootdirectory}->[0]->{subdirectory}->[0]

and receive the expected answer of 'file1'.

My problem comes from all of the a priori knowledge I need to derive my filename in the above example. As I am trying to allow the users of my script to describe an arbitrary directory structure in the YAML configuration this isn't good enough. I need to be able to "walk" the tree from 'rootdirectory'.

So, I would have imagined I could have done something like this:

print keys($configuration->[0])

which I would have expected to have returned 'rootdirectory,version' ... and so on, iterating over the arrays and hashes until I had walked the tree.

When I attempt to run the above example, I get:

Type of arg 1 to keys must be hash (not array element)

At this point I am stuck. As I understand it, $configuration->[0], whilst being an element of an array, is an element containing a hash that I believe I should be able to invoke the keys function against.

What am I missing here?

like image 664
sam_pointer Avatar asked Aug 12 '09 16:08

sam_pointer


1 Answers

Try

print "$_\n" for keys %{ $configuration->[0] };

You have to force the array element "$configuration->[0]" into a hash ref with "%{...}"

So to iterate over them:

for my $key ( keys %{ $configuration->[0] } ){
  my $value = $configuration->[0]{$key};

  print "$key => $value\n";
}
like image 139
Brad Gilbert Avatar answered Oct 01 '22 23:10

Brad Gilbert