Hello lairel,
When I run your code with perl -c, I get the following output:
16:16 >perl -c 1583_SoPW.pl Global symbol "$headerHash" requires explicit package name (did you fo +rget to declare "my $headerHash"?) at 1583_SoPW.pl line 59. 1583_SoPW.pl had compilation errors (#1) (F) You've said "use strict" or "use strict vars", which indicates that all variables must either be lexically scoped (using "my" or +"state"), declared beforehand using "our", or explicitly qualified to say which package the global variable is in (using "::"). Uncaught exception from user code: Global symbol "$headerHash" requires explicit package name (di +d you forget to declare "my $headerHash"?) at 1583_SoPW.pl line 59. 1583_SoPW.pl had compilation errors. 16:16 >
What this is telling you is that the variable $headerHash is being used where it hasn’t been declared. That’s because a variable declaration with my (which produces what is called a lexical variable) has a scope which is limited to the block where it occurs (see e.g. the tutorials in Variables and Scoping). So in this code:
while (<INFILE>){ chomp; my $line = $_; ... if ($line =~ /^>/){ my $header = $line; if ($header =~ /(>gi.*)\[(.+)\](>gi.*)\[(.+)\]/){ my $headerHash; # A $headerHash{$1} = $2; } else{ my $seq = $line; print OUTFILE $headerHash, "\n", $seq, "\n"; # B } } }
the declaration at point A has gone out of scope by the time the variable is referenced at point B. To fix this, you need to give the variable a wider scope, by declaring it before you enter the if/else construct:
while (<INFILE>){ chomp; my $line = $_; my $headerHash; ... if ($line =~ /^>/){ my $header = $line; if ($header =~ /(>gi.*)\[(.+)\](>gi.*)\[(.+)\]/){ $headerHash{$1} = $2; } else{ my $seq = $line; print OUTFILE $headerHash, "\n", $seq, "\n"; } } }
But while this will remove the compile error, it doesn’t make a lot of sense: you print out the value of $headerHash only if its value has not been initialised! Perhaps you need to declare $headerHash before the while loop? In any case, a line such as:
print OUTFILE $headerHash ...
will only result in output like this:
16:17 >perl -wE "my $h = { a => 1, e => 2 }; print STDOUT $h;" HASH(0x3ac320) 16:30 >
which is not what you want. Please supply a sample input file, together with the output you want to produce from that file (see How do I post a question effectively?). This will help the monks to understand what you’re really trying to achieve.
Update:
Until I read Marshall’s reply, I hadn’t noticed that %headerHash is already declared before the loop; I was reading the line $headerHash{$1} = $2; as though it were this: $headerHash->{$1} = $2; — i.e., treating $headerHash as a hash reference — which of course it isn’t. :-(
lairel, just to emphasise the point Marshall is making: in Perl, $headerHash, @headerHash, and %headerHash are separate, completely unrelated variables. $headerHash{$key} references one element of the hash %headerHash, and is unrelated to the scalar variable $headerHash.
Hope that helps,
| Athanasius <°(((>< contra mundum | Iustus alius egestas vitae, eros Piratica, |
In reply to Re: While loop with nested if statements (updated)
by Athanasius
in thread While loop with nested if statements
by lairel
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |