http://qs321.pair.com?node_id=348708

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

Morning Monks,

Still kind of new to Perl and was hoping for some Perl wisdom from anyone out there... have just recently started trying to develop my own Package(have checked CPAN and couldnt find an existing one) that handles the Logical Volume Manager LVM for AIX.

My question is more on proper coding style more than anything but given a command...

lsvg -l rootvg
this returns the following data
LV NAME TYPE LPs PPs PVs LV STATE MOUNT hd5 boot 1 2 2 closed/syncd N/A hd6 paging 64 128 2 open/syncd N/A pdumplv sysdump 64 64 1 open/syncd N/A hd8 jfslog 1 2 2 open/syncd N/A hd4 jfs 5 10 2 open/syncd / hd2 jfs 122 244 2 open/syncd /usr hd9var jfs 33 66 2 open/syncd /var hd3 jfs 49 98 2 open/syncd /tmp hd1 jfs 47 94 2 open/syncd /home
Given this data, what would be the best way to return the data from the package to a script that calls it?
Should the pacakage return a nested hash or six individual hashes which corresponds to each of the headings except for "LV NAME", which would be used as the index. Or perhaps use something like Class::Struct ??? Though with Class::Struct not being a standard package i was a little weary of using it

TIA

Replies are listed 'Best First'.
Re: How best to return data from a package ???
by kvale (Monsignor) on Apr 28, 2004 at 03:48 UTC
    It seems to me that the data is much more strongly bound together row-wise than column-wise. People who use this will probably want to access information about logical volumes, i.e., they will want to treat LV NAME as a primary key. So I would recommend the hash structure as most natural:
    $value = $hash->{$lv_name}{$attribute};
    Presenting the data in parallel arrays requires one to think about an abstract index to synchronize data extraction, which is less intuitive than the LV NAME.

    -Mark

Re: How best to return data from a package ???
by TomDLux (Vicar) on Apr 28, 2004 at 04:01 UTC

    What kvale said.

    I"m posting to ratify and also to clarify. The top level data structure, %lvm_data, perhaps, would have the keys, 'hd1', 'hd2', 'hd3', 'hd4', 'hd5', 'hd6', 'hd8', 'hd9var', and 'pdumplv'. Each of these would have the keys, 'type', 'lps', 'pvs', 'state' and 'mount'.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

      thanks guys, after reading more and getting a better understanding of hashes of hashes i think this is what im after for my package. I think i was just overcomplicating the problem by trying to break the data structure down into too many different pieces ... anyways thanks again
Re: How best to return data from a package ???
by jdporter (Paladin) on Apr 28, 2004 at 04:10 UTC
    I would return a list of "records", where each record is implemented as a hash. E.g.
    my $infh = IO::File->new("< data") or die; local $_ = $infh->getline; s/LV /LV_/g; # :-) my @column_names = split; my @records; while ( $infh->getlines ) { my %rec; @rec{@column_names} = split; push @records, \%rec; } return @records; # or simply return map { my %r; @r{@c} = split; \%r } $infh->getlines;

    ...just for example. A better approach would parse fixed-width columns. A more robust extension of that would attempt to infer the column widths.

    Update. If one of the columns is a "unique key", then it probably makes sense to load the set of records into a hash, using those values as the hash keys. E.g.:

    return map { my %r; @r{@c} = split; ( $r{'LV_NAME'} => \%r ) } $infh->getlines;
    (That doesn't really return a hash, it returns a list... but that list can sensibly be assigned to a hash and it will DWIM.)
Re: How best to return data from a package ???
by William G. Davis (Friar) on Apr 28, 2004 at 06:31 UTC
    Or perhaps use something like Class::Struct ??? Though with Class::Struct not being a standard package i was a little weary of using it.

    Actually, Class::Struct *is* a standard package (by standard package I'm guessing you mean a core module); it comes with Perl, as it has since at least version 5.004. Though I don't think you really need it anyway.