enikao has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm experienced in several programming languages, but Perl beats me /-: So I ask you people wiser than me for help.

I want to amend a Perl program (JSDoc) with new functionality. The basic task is simple: We have a deep structure and want to retrieve specific items, putting them into a new structure. The source structure looks like this (I stripped everything not relevant):

$VAR1 = { 'classes' => [ { 'classid' => 'xmi.2', 'classdescription' => undef, 'methods' => [ { 'methoddescription' => '', 'methodid' => 'xmi.77', } ], 'attributes' => [ { 'attributedescription' => '', 'attributeid' => 'xmi.75', } ], }, { 'classid' => 'xmi.3', 'classdescription' => '', 'methods' => [ { 'methoddescription' => '', 'methodid' => 'xmi.82', } ], 'attributes' => [], } ] };
We want a flat list of ids and descriptions like this:
$descriptions = [ { 'id' => 'xmi.2', 'description' => undef, }, { 'id' => 'xmi.77', 'description' => '', }, { 'id' => 'xmi.75', 'description' => '', }, { 'id' => 'xmi.3', 'description' => '' }, { 'id' => 'xmi.82', 'description' => '', } ];
The basic flow is obvious:
FOREACH class PUT classid, classdescription INTO descriptions FOREACH method PUT methodid, methoddescription INTO descriptions END FOREACH FOREACH attribute PUT attributeid, attributedescription INTO descriptions END FOREACH END FOREACH

I've tried this for several hours now, but I got mixed up in arrays, hashes, pseudo-hashes, etc.

Any hints are greatly appreciated.

Niko

Replies are listed 'Best First'.
Re: Retrieving data from deep structure
by kennethk (Abbot) on Dec 05, 2008 at 23:08 UTC

    Just a note about your structure - Your methods and attributes above are defined to be arrays with only one element. That's certainly an unnecessary complication. I'm wondering if someone went to all the bother of creating such a complex structure if they didn't also define accessor methods for you to use.

    my @descriptions = () for my $class (@{VAR1{classes}}) { my %local_hash = (); $local_hash{id} = $class->{classid}; $local_hash{description} = $class->{classdescription}; push @descriptions, {%local_hash}; for my $method (@{$class->{methods}}) { my %local_hash = (); $local_hash{id} = $method->{methodid}; $local_hash{description} = $method->{methoddescription}; push @descriptions, {%local_hash}; } for my $attribute (@{$class->{attributes}}) { my %local_hash = (); $local_hash{id} = $attribute->{attributeid}; $local_hash{description} = $attribute->{attributedescription}; push @descriptions, {%local_hash}; } }

    Update:Fixed typos.

      kennethk, thank you very much! A little more tweaking, at now it works. I'm posting the final function (just for reference for others seeking like me):
      sub get_descriptions { my ($self, $packages) = @_; my @descriptions = (); for my $class (@{$packages->{classes}}) { my %local_hash = (); $local_hash{id} = $class->{classid}; $local_hash{description} = $class->{classdescription}; push @descriptions, {%local_hash}; for my $method (@{$class->{methods}}) { my %local_hash = (); $local_hash{id} = $method->{methodid}; $local_hash{description} = $method->{methoddescription} +; push @descriptions, {%local_hash}; } for my $attribute (@{$class->{attributes}}) { my %local_hash = (); $local_hash{id} = $attribute->{attributeid}; $local_hash{description} = $attribute->{attributedescri +ption}; push @descriptions, {%local_hash}; } } @descriptions; }

      For your note: I agree for the example the arrays are not neccessary, but there can be multiple methods or attributes (it's an UML XMI generator). As far as I understood the code, there are no accessor methods (the already existing part of the generator retrieves its data in the same way).

      Thank you again, this helps me a lot!

      Niko

      PS: Is there a good reference where I can learn the subtleties of scalars, arrays and hashes? I understand the basic difference, but I'm totally at a loss when to use which prefix (e. g. my %local_hash = (); vs. $local_hash{id} vs. $class->{methods}).

        PS: Is there a good reference where I can learn the subtleties of scalars, arrays and hashes? I understand the basic difference, but I'm totally at a loss when to use which prefix (e. g. my %local_hash = (); vs. $local_hash{id} vs. $class->{methods}).
        perldata; and, for the fancy stuff, perldsc.
Re: Retrieving data from deep structure
by planetscape (Chancellor) on Dec 06, 2008 at 06:32 UTC