Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

adding a new hash in an array

by popsin (Initiate)
on Jul 14, 2004 at 16:10 UTC ( #374335=perlquestion: print w/ replies, xml ) Need Help??
popsin has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I have the following problem:
I have a CGI script that reads data from a text file and sends it to HTML::Template in TMPL_LOOP. Every row in that file has a key and value pair. Here is a part from that script:
foreach $line (@lines) { ($name, $value) = split(/=/, $line); chomp($name); chomp($value); if ($name eq "loop" and $value eq "start") { $loop_status = "start"; } if ($loop_status eq "start") { if ($name eq "loop_name") { $loop_name = $value; } elsif ($name eq "loop" and $value eq "end") { $loop_status = "end"; $template->param(eval "$loop_name" => \@loop); } elsif ($name eq "row" and $value eq "start") { my %row; } elsif ($name eq "row" and $value eq "end") { push (@loop, \%row); } else { if ($name ne "loop") { $row{eval "$name"} = $value; } } } if ($loop_status ne "start") { if ($name ne "loop" and $name ne "loop_name" and $name ne "row" an +d $name { $template->param($name, $value); } } }
But it doesn't work what I expect. I get all rows with the same values as in the last row read from the text file. This is what I get when I check the @loop array:
$VAR1 = [ { 'rel_date' => '04/060/09', 'importer' => 'Something', 'file_id' => '123', 'vendor' => 'Some', 'urgency' => '5' }, $VAR1->[0], $VAR1->[0], $VAR1->[0], $VAR1->[0] ];
It seems that it does not create new hash %row when it goes through the loop.

Any suggestions?
Thanks

Comment on adding a new hash in an array
Select or Download Code
Re: adding a new hash in an array
by Roy Johnson (Monsignor) on Jul 14, 2004 at 16:39 UTC
    You're declaring %row in a different block from where you push it, so the one being pushed is a global. Put my %row in the same block as it is used. I recommend just after the chomps.

    Also, use strict; at the top of your code would alert you to such things (unless you've declared my %row outside of the foreach loop.


    We're not really tightening our belts, it just feels that way because we're getting fatter.
Re: adding a new hash in an array
by matija (Priest) on Jul 14, 2004 at 16:40 UTC
    Ouch, your code is a MESS! The only thing that could make it look uglier is a couple of gotos.

    Your basic problem is that you are running without use strict; with it, you would realize that the code

    { my %row; }
    does not do what you think it does.

    You need to put the my outside of the loop, and instead of simply assigning new values to the hash, you need to make sure each row gets it's own anonymous hash.

    The way I usualy do it looks somewhat like this:

    foreach (@rows) { push(@arr,{}); $cnt++; # .... code ... $arr[$cnt]{somestring}=$somevalue; }
    Actually, I usualy fill in the values right when I allocate the anonymous hash, but that couldn't be translated into what you need as easily.
      Thanks,

      This is the code that works:

      my @arr; my $loop_status; my $loop_name; MAINLOOP: foreach $line (@lines) { ($name, $value) = split(/=/, $line); chomp($name); chomp($value); if ($name eq "loop" and $value eq "start") { $loop_status = "start"; next MAINLOOP; } if ($name eq "loop_name") { $loop_name = $value; next MAINLOOP; } if ($name eq "loop" and $value eq "stop") { $loop_status = "stop"; $template->param(eval "$loop_name" => \@arr); next MAINLOOP; } if ($loop_status eq "start") { if ($name eq "row" and $value eq "start") { $cnt++; push(@arr,{}); next MAINLOOP; } $arr[$cnt]{eval "$name"} = $value; } else { $template->param($name, $value); } } print "Content-type: text/html\n\n"; print $template->output;

      I know my code is a mess :-(
      But it works fine now.
      I tried to put use strict but I got the whole bunch of error messages so I will skip it.

      Another question:
      Is there a standard way to store session variables?

        I tried to put use strict but I got the whole bunch of error messages so I will skip it.

        That's the whole point of use strict. Those error messages are telling you why your code is broken. You would never have run into the problem you just had if your code was strict-compliant.

        Is there a standard way to store session variables?

        Indeed. Check out CGI::Session.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://374335]
Approved by VSarkiss
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (7)
As of 2014-12-27 03:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls