Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

use strict seems to hose my code

by aeshirey (Initiate)
on Apr 24, 2002 at 20:07 UTC ( #161762=perlquestion: print w/ replies, xml ) Need Help??
aeshirey has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a CGI program that is currently of a decent length (almost 700 lines). Until recently, I did not have "use strict," (I'm a novice) so I decided to implement it and run through my code, making sure all variables had "my" and proper scope.

After eliminating all errors (by the way, I do use the -w option), my code *says* it runs fine, but at least one hash doesn't get values from the form(s) I use. I've found that when I initialize my %INPUT for my form, all values are null, even though they previously worked fine before the use strict implementation. In my block that gets STDIN and puts into $buffer, I try to print each key and value as it's put into the hash, but my program won't print them. In fact, it won't print ANYTHING, even hard-coded text.

Also, I've tried removing the "my %INPUT;" line and "undoing" some of the strict coding to (hopefully) allow it to temporarily work so I can figure out what went wrong and where. Unfortunately, this doesn't bring back my %INPUT, and I'm pretty much dead in the water.

No compiler errors/warnings, no way to tell why it's not working. I've searched elsewhere, but found no answer. Does anyone have any insight as to why my hashes aren't working?

Thanks,
Adam

Comment on use strict seems to hose my code
Re: use strict seems to hose my code
by ignatz (Vicar) on Apr 24, 2002 at 20:20 UTC
    It's a lot harder to debug code when you can't see it. :-)

    Could you strip it down to the smallest form that duplicates the problem and post it up here?

    ()-()
     \"/
      `                                                     
    
Re: use strict seems to hose my code
by davorg (Chancellor) on Apr 24, 2002 at 20:22 UTC

    Sounds like you've learned a valuable lesson there. Adding use strict after finishing your script isn't anywhere as easy as using it right from the start.

    As for your actual problem, it's almost impossible to help without seeing any code.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: use strict seems to hose my code
by dws (Chancellor) on Apr 24, 2002 at 20:23 UTC
    ... making sure all variables had "my" and proper scope.

    A common problem I've seen when people introduce strict-ness at a late date is when they prepend "my" to a variable at first use, which trims the lifetime of the variable. If there's a later use beyond the first scope, oops. Perhaps you lost a global.

    Show us some code.

Re: use strict seems to hose my code
by Dog and Pony (Priest) on Apr 24, 2002 at 20:26 UTC
    Please post (at least critical parts of) your code, otherwise it is very hard to analyze what is happening.

    But the real advice I am going to give is do not parse your POSTS (or anything else CGI) by yourself, use CGI.pm instead, and it *will* work. Other than as an interesting exercise to learn more about the inner workings of the HTTP and CGI protocols, you should never do this on your own. Your own wheel will very unlikely be as round, neat and well pumped as CGI.pm. :)


    You have moved into a dark place.
    It is pitch black. You are likely to be eaten by a grue.
(cLive ;-) Re: use strict seems to hose my code
by cLive ;-) (Parson) on Apr 24, 2002 at 20:26 UTC
    And the reason you're not using CGI is?

    .02

    cLive ;-)

Some code
by aeshirey (Initiate) on Apr 24, 2002 at 20:38 UTC
    Thanks for your replies. I didn't post code initially because I didn't think people would appreciate me dumping the problem directly onto them. But here's the relevant code:

    Immediately after the relevant beginning lines, I create three hashes I'll use. %INPUT is the one in question. I haven't got it far enough to know if the other two work. We all know %ENV, and %CFG has values from a config file I load.

    my (%INPUT,%CFG,%ENV);

    To clean up my "main" program, I dump off the initialization of %INPUT to a subroutine, which I call immediately after my variable declarations (save a few comments in between):

    my ($buffer,$name,$value,@pairs,$pair); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { $name, $value) = split(/=/, $pair); $value =~ tr/+/ /; value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $INPUT{$name} = $value; print "\$INPUT{$name} = $value<br>"; }


    That last line was put in to help me see if any of the values are printed. I expected it to at least print "$INPUT{} = " (null for the actual values), but in fact, it didn't print anything.

    Even if I put this code immediately after the above "my (...)" code, it still doesn't give me any output.
      Maybe you stripped more than what you had to to post your code here, but from what I can see,
      my ($buffer,$name,$value,@pairs,$pair); @pairs = split(/&/, $buffer);

      you are acting on an empty $buffer: the my declaration of $buffer 'initializes' it, so when you use split() to get the values from it, you are acting on an 'empty' variable. You might want to move that

      my ($buffer);
      a little higher on your script.

      Do you get any warnings that tell you you are acting on undefined data? try printing $buffer before and after the split(), because it might tell you the problem is there...

      Update: you say you don't even get 'empty' lines printed, which tells me you never run the for() loop... try to print() @pairs before entering the for()

      hope this helps,

      First, what you have there is one of the oldest bits of hand-recopied Perl code on the Internet. It's from the original cgi-lib.pl by a nice fella named Steve Brenner. You should use CGI. See use CGI or die; for why.

      Next, %ENV is a global variable. Putting it in a my declaration will wipe it clean. Thus there will be no $ENV{'QUERY_STRING'}, no $ENV{'CONTENT_LENGTH'}, thus no $buffer, and thus no output. There's no need to try to localize %ENV; strict knows it's a global and won't yammer.

      Update: Never mind %ENV, $buffer is empty. Use CGI instead. :)

      stephen

Re: use strict seems to hose my code
by dsb (Chaplain) on Apr 24, 2002 at 21:13 UTC
    my localizes the variable being declared to the current block, so if you are declaring a variable in a loop, and then try to access it outside of that loop you'd get a Global symbol XXXX requires explicit package name error running the script from the command line.
    use strict; foreach (0 .. 5) { my $foo++; } print $foo, "\n"; # throws error




    Amel
Re: use strict seems to hose my code
by Sifmole (Chaplain) on Apr 25, 2002 at 12:09 UTC
    To parrot/sum up/paraphrase several of the above answers:

    use CGI;

    And dump the whole blinking block. You have copied a chunk of code that you exhibit not even the slightest understanding of and that is both bad practice and dangerous.

Re: use strict seems to hose my code
by aeshirey (Initiate) on Apr 25, 2002 at 14:10 UTC
    I've replaced the original code by:
    use CGI; my ($q,$INPUT); undef %$q; $q = new CGI; $INPUT = $q->Vars;
    As far as Sifmole's statement that I have no understanding of what my previous code did: I fully understood it. I greatly appreciate everyone's help, but I learned CGI using that block of statements, not "use CGI"; consequently, it took more work than just adding "use CGI" in there. For example, I didn't know I'd have to create a new CGI scalar.

    Everything works nicely now. Thanks to everyone for your help :)

    -Adam

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2014-10-21 06:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (97 votes), past polls