in reply to Problems with Variable Scope in Perl

The first problem I see is that you increment "$count" as soon as you put the first line of each entry into each of your arrays. Then when you hit the second line of each entry, $count is putting the long string of letters into the next element of your "pdbString" array. So when you go to print to your output file(s), you are getting the wrong pdbString data for each entry (and this string is empty/undefined for the first entry).

(Update: Forgot to mention: because of the way you used your $count variable, all the "pdbString" values end up as empty strings: you increment $count before you store the string in that array, then when you hit the start of the next entry, you assign "" (empty string) to that same array element.)

Here's a cleaned up version of your code, with "use strict" included (because that's what all good monks do), and a fair bit of seemingly unnecessary stuff left out.

#!/usr/bin/perl -w use strict; my ( @PDBchain, @PDBcode, @pdbString, @SCOPclass ); open (IN, $ARGV[0] ); while (<IN>) { chomp; if ( /^>d(\d\w{3})(\w[_\d])\s(\w)/ ) { push @PDBcode, $1; #SAVE PDB CODE push @PDBchain, $2; #SAVE PDB CHAIN push @SCOPclass, $3; #SAVE SCOP CLASS (A,B,C,D,E,F,G) push @pdbString, ""; } else { $pdbString[$#pdbString] .= $_; } } close IN; print "Total number of entries: ".scalar( @PDBcode ). "\n"; #COUNT TOT +AL NUMBER OF PDBS REPRESENTED for ( 0 .. $#PDBcode ) { open (OUT, ">>$PDBcode[$_]_$PDBchain[$_].fa"); print OUT ">",$PDBcode[$_], "_", $PDBchain[$_], "\n"; print OUT $pdbString[$_], "\n"; close OUT; }
Given the input you showed, that produces two output files, with one entry in each file. BTW, the OP code saved stuff into a "@SCOPclass" array, but then never used it. Was that intentional?

Oh, another thing about the OP code: the last two print statements of the while loop are never reached. That's okay, you don't need them anyway, but proper indentation of your code might help to avoid misunderstandings.

Replies are listed 'Best First'.
Re^2: Problems with Variable Scope in Perl
by Anonymous Monk on Nov 03, 2008 at 01:12 UTC

    Thank you very much Graff! Yes, saving the @SCOPclass array is intentional. One more question though: could you kindly explain:

    $pdbString[$#pdbString] .= $_;

    What do the $ followed by # represent? As I am still new at Perl I get confused between these symbols! Thanks for all your help :)

      The string contained in $_ is being joined to the string in the last element of @pdbString This code could also be written as:
      $pdbString[@pdbString - 1] .= $_;
      or
      $pdbString[-1] .= $_;
      Which I find simpler to read (negative index references the array starting from the end).

      $#pdbString is the index of the last element in array @pdbString. There are more examples and explanations in perldata.

      Yes, saving the @SCOPclass array is intentional.

      ... and so the fact that you never use the saved values would seem to be unintentional?

        I have saved the @SCOPclass array but I am still figuring out what I want to do with it in the scope of my work! So yes, saving the values is intentional, but where I want to output the variable and how I want to use the saved values remains unintentional :)