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

Hi there
Some of you might remember me posting a problem called 'headache with array'. I got a wealth of good advice and went away to implement it.
Anyway, i still appear to be doing something wrong because i cant get the contents of the hash of arrays to print at the end of the script. What I want the script to do is to populate the array using all the files in the directory and then print it. I've managed to print the array for each file, but I actually need it after all the files have been processed if that makes sense. Here is the relevant bit of the script. Any advice much appreciated.
for($i = -180; $i < 181; $i = $i+5) { $j = $i+5; $n++; $o = 0; for($k = -180; $k < 181; $k = $k+5) { $m = $k+5; $o++; my @ranges = ([$i, $j, $k, $m]); my @range_counts = (0) x @ranges; # open .out file created by secondary_structure.pl script to c +heck date of crystal structure # was structure created before or after the advent of procheck +? open(FILE, "$dir$file") || die "ERROR: Unable to open $dir$fil +e FILE: $!\n"; @file = <FILE>; foreach $record(@file) { # print "$record\n"; #extract relevant information from file # is residue a GLY or a NON-GLY residue? $residue = substr($record, 0, 3); if($residue ne "GLY") { $residue = "NONGLY"; } $phi = substr($record, 7, 6); $psi = substr($record, 14, 6); $secondary_structure = substr($record, 21, 1); #print "1 $secondary_structure $residue $procheck\n"; #print "2 $sec_struct $selectresidue $selectprocheck\n"; if(("$secondary_structure" eq "$sec_struct") && ("$residue" eq "$selectresidue") && ("$procheck" eq "$selectprocheck")) { for my $R (0..$#ranges) { if ($phi >=$ranges[$R][0] and $phi < $ranges[$R][1] and $psi >= $ranges[$R][2] and $psi < $ranges[$R][3]) { ++$range_counts[$R]; } } } } } } } for my $R (0..$#ranges) { if($v < 73) { printf "%d, ", $range_counts[$R]; $v++; } else { print "\n"; $v = 0; } }
Thanks a lot

Replies are listed 'Best First'.
Re: folow up to headache with array
by ikegami (Patriarch) on Sep 28, 2004 at 16:38 UTC

    1) You need use strict; use warnings;. Each time you go through the loop, you create a new @range_counts. Notice the my within {}. Furthermore, the print uses the global @range_counts, not one of those in which you placed values, since they went out of scope. Put my @range_counts; at the very top.

    2) @ranges = ([$i, $j, $k, $m]); create a single element in @ranges. Is that really what you want to do? In your code, $R will always be 0, and for my $R (0..$#ranges) will always loop only once.

    3) You spoke of "hash of arrays", yet there are no hashes in that program.

    4) I couldn't help but noticing you're reading the same file over and over and over and over again. That's rather innefficient. Especially since you put the contents of the file in an array. Why not populate @file only once?

    I can't help you more (and I'm surprised I helped you this much) since you didn't provide a sample input and the desired output for that input.

Re: folow up to headache with array
by BrowserUk (Patriarch) on Sep 28, 2004 at 16:41 UTC

    The cause of your problem is scoping. Just about the only variable that needs to have a wide scope ( @range_counts ) is one of the 2 or 3 that you've chosen to use my on...?

    If you dropped the my on that variable, or declared it with my above the first for loop in your snippet, then your last for loop would be able to see it and it's contents.

    Of course, if you re-wrote your script to use strict and use warnings, perl would have told you that the @range_counts array you are accessing in you last loop is an entirely different (global) array from the one you are creating with my inside the first set of for loops. Being lexical, this @range_counts has gone out of scope by the time you reach the second for loop.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon