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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.