The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Perl Question Array Question

I'm a complete NOOB when it comes to Perl and I was recently asked to complete a Perl script that another guy didn't complete and left the company.  (hope it's ok to post this here, so here goes).

The script reads in a number of config files all with the same format as follows:

parameter1 value1
parameter2 value2

parameter1 value1
parameter2 value2

The Perl script reads all the files and stores the values into an array like so:

$Settings{$ProjectName}{$key} = "@values";

Where $ProjectName = the file name (config-1, config-2, etc...) and $key is equal to parameter1, parameter2, etc...

No errors are met with during the running of the script.  Now in my job is to do more with the script so I wrote some small routine to print a list of the array like so:

 for $i (0 .. $#Settings )
    $row = $Settings[$i];
    for $j (0 .. $#{row} )
      print "element $i $j = $row->[$j]\n";

And it would not work!  Why?

And when I do a
print "Settings Size = ", $#Settings, "\n\n";

it always comes back with a -1. 

Is this due to the fact we are using named references for our array instead of numbers for columns and rows?

ie $Settings{x}{y} = "@values"; where x & y = 0, 1, 2, etc...?
Perl Noob
Wednesday, December 07, 2005
The {} indicate a hash, not an array. So instead of your existing iteration you might try:

while ( my ( $project, $key ) = each %Settings ) {
    print "Item at $project $key: $Settings{ $project }->{ $key }\n";

Also, I'm pretty sure that this:

$Settings{$ProjectName}{$key} = "@values";

is not doing what you think it's doing. What it's actually doing is interpolating the @values array into a string, using the default field separator (,). You probably want a reference to the array instead:

$Settings{$ProjectName}->{$key} = \@values;

Take a look at 'perldoc perlref' to learn more about references and nested data structures.
Chris Winters Send private email
Thursday, December 08, 2005
You are confusing associative arrays (Perl hashes) with regular arrays.  When you create the multi-level hash (hash of hashes), like so:

    $Settings{$ProjectName}{$key} = "@values";

You need to iterate over them like so:

for my $project (sort keys %Settings)
    for my $key (sort keys %{$Settings{$project}})
        print "Project $project Key $key => $Settings{$project}{$key}\n";

Note the use of 'my'.  The second for loop is definitely tricky.
Jonathan Leffler Send private email
Saturday, December 10, 2005
Saturday, December 10, 2005
>using the default field separator (,)

When I tried it I got spaces:

knoppix@ttyp0[home]$ cat

@abc = (1,2,3);
$xyz = "@abc";
print "$xyz\n";

knoppix@ttyp0[home]$ perl
1 2 3

This was with release 5.8.7, but I don't think that makes any difference.
dot for this one
Saturday, December 10, 2005
memory fart on two counts: the default field separator is '', and a 'field' in a print statement is an item in the argument list rather than the interpolated list. You can change the field separator with '$,', so:

my @values = ( 1, 22, 33 );
print "Default: ", @values, "\n";
$, = ',';
print "Assigned: ", @values, "\n";

will print:

Default: 12233
Assigned: ,1,22,33,
Chris Winters Send private email
Sunday, December 11, 2005
If you simply want to see the contents of your data structure, just use Data::Dumper.


use strict;
use Data::Dumper;

my %Settings;
while (<DATA>) {
    next if /^\s*$/;
    my ($k, $v) = split;
    $Settings{'config-1'}{$k} = $v;

print Dumper \%Settings;

parameter1 value1
parameter2 value2
parameter3 value3
parameter4 value4
Monday, December 12, 2005

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz