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

Hi Everyone, I'm fairly new to Perl through been using it for a while I never really go into the 'use Strict thing'. Now I’m writing me Perl code I want to start doing a better job of it.

Anyway when I use 'use strict' on the CGI below I get errors about the '$IMPUT' variable and that I should declare it. I’ve tried putting my in front of it when I pass the values in into it and even creating a empty version at the start of the script with ‘My $INPUT = “”;’ but I just can’t figure it out. I’m sure it’s real simple but I’ve spent a day looking for the answer with no luck. Thanks in advance guys.

#!c:/Perl/bin/Perl.exe -w use strict; use CGI; print "Content-type: text/html\r\n\r\n"; # PDF 2 JPEG CGI my $INPUT = (); &DecodeInURL(); my $PDF2JPGEXE = 'C:\_TestSite\PDF2JPG\bin\pdf2jpeg.exe'; my $PDFFile = $INPUT{"file"}; print "**$PDFFile<br>"; my $output = 'Out_Temp\TempPDF%3.3d.jpg'; my $PDF2JPG_OutPut = system("$PDF2JPGEXE -w -d 90 -q 80 -s 240 300 -f + $PDFFile $output"); print "<p>Output: $PDF2JPG_OutPut"; sub DecodeInURL { my $Decoded = $ENV{'QUERY_STRING'}; #Get Method $Decoded =~ s/%([\a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; print "$Decoded\n"; my @INPUTVars = split /\&/ , $Decoded; foreach my $pair (@INPUTVars) { if ($pair=~m/([^=]+)=(.*)/) { my $field = $1; my $Value = $2; $Value =~ s/\+/ /g; $INPUT{$field}=$Value; return $INPUT; } } }

Replies are listed 'Best First'.
Re: Use Strict & subs
by duff (Parson) on Dec 30, 2004 at 05:08 UTC

    $INPUT is declared just fine, but %INPUT however is not. And %INPUT is the variable you're using when you say $INPUT{$field}=$Value;

Re: Use Strict & subs
by Errto (Vicar) on Dec 30, 2004 at 05:40 UTC
    A more general comment: if you are going to use CGI, you should take advantage of the functionality that it offers you. First, you should create a CGI object by saying my $q = CGI->new. Then your input parsing line would look like my $PDFFile = $q->param("file"); and you don't need any variables like $INPUT or %INPUT. You also don't need DecodeInURL - just get rid of it. Furthermore, instead of print "Content-type: text/html\r\n\r\n"; you could simply use print $q->header("text/html");. Finally, though you may know this already, I should point out that the call to system does not return the output of the "pdf2jpeg" command, but rather its exit code, which is just a number. So this number is what will be displayed on the line that says "Output:" I'm not sure how exit codes work in Windows, but in Unix, and exit code of zero means success.
      Just a little comment.
      i'd be careful using CGI, this module is a real good hack, but BIG (using 3,5 mb of your memory when compiled).
      Next, i don't really like the idea of using the html stuff CGI offers, i like my perl code to be perl, not html. You might Have a look at HTML::Template, or try the Tal implementation for perl: Petal.
      I don't want to create a flame about CGI versus other methods (like Apache::Request), but i'd like to inform about the possibilities, since CGI might not be the best solution for some problems.

      hmm updated since last comment:
      I'd use either the module HTML::Template or Pental (the Plone template system) to conform more to the Model-View-Controller patterns, and use templates and these modules to generate the html-content in stead of CGI

      Next i'd use the Apache::Request implementation to read any requests, it has the same interface as CGI, but is light and fast in use.
      More information can be found on http://www.cpan.org and www.plone.org.
        While technically true, your comment would be better suited if you explained further why someone should use HTML::Template instead of CGI. Furthermore, what is a "Tal" implementation?

        For the record, I know what those things are. But, you're giving an answer to someone who doesn't seem to have a lot of domain experience in the web applications world. You need to explain what you're talking about and why someone should make a radical paradigm shift.

        Being right, does not endow the right to be rude; politeness costs nothing.
        Being unknowing, is not the same as being stupid.
        Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
        Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        i'd be careful using CGI, this module is a real good hack, but BIG (using 3,5 mb of your memory when compiled).

        It's worth pointing out that whilst it's true that CGI.pm contains a lot code, it also implements a pretty ingenious code loader that it only actually compiles the code that you use. So you shouldn't really worry about loading code that you aren't going to use - CGI.pm is actually pretty efficient.

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

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

Re: Use Strict & subs
by Mayhem50 (Novice) on Dec 30, 2004 at 05:30 UTC
    Thanks Duff i just added a 'My %Input =();' and away it went. I 've never delt with a hash other than set out like this '$INPUT{$field}=$Value;' and when use strict is off it works just fine. How newb was that, Thanks again!
Re: Use Strict & subs
by swaroop.m (Monk) on Dec 30, 2004 at 14:44 UTC
    I guess your intention is the following.
    use strict; use CGI; print "Content-type: text/html\r\n\r\n"; # PDF 2 JPEG CGI my %INPUT = &DecodeInURL(); my $PDF2JPGEXE = 'C:\_TestSite\PDF2JPG\bin\pdf2jpeg.exe'; my $PDFFile = $INPUT{"file"}; print "**$PDFFile<br>"; my $output = 'Out_Temp\TempPDF%3.3d.jpg'; my $PDF2JPG_OutPut = system("$PDF2JPGEXE -w -d 90 -q 80 -s 240 300 -f + $PDFFile $output"); print "<p>Output: $PDF2JPG_OutPut"; sub DecodeInURL { my $Decoded = $ENV{'QUERY_STRING'}; #Get Method my %INPUT; $Decoded =~ s/%([\a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; print "$Decoded\n"; my @INPUTVars = split /\&/ , $Decoded; foreach my $pair (@INPUTVars) { if ($pair=~m/([^=]+)=(.*)/) { my $field = $1; my $Value = $2; $Value =~ s/\+/ /g; $INPUT{$field}=$Value; return %INPUT; } } }
Re: Use Strict & subs
by sasikumar (Monk) on Dec 30, 2004 at 05:51 UTC
    Hi Mayhem50

    Perl treats $INPUT{$field} as a hash variable. without using stricts it works because it will lexically create a variable called %INPUT inside the sub. So it would work well without using strict. When you use strict , we need to explicitly declare the variable.So be sure what data type you would want to use. if you need a scalar $INPUT then remove $INPUT{$field}=$Value; as this is not the right way to store a value in scalar. Else if you want to store a vector ie hash then declare your variable as my %INPUT=(); and also remove the return $INPUT statement.

    NOTE: FYI %INPUT and $INPUT are two different varibales and can coexist. so you can declare  my ($INPUT,%INPUT);

    Thanks
    SasiKumar