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

what do these mean is there a problem with my cgi::carp module???
C:\Perl>perl -c [Tue Aug 21 19:57:32 2001] (eval 1): Array found where operator expect +ed at (ev l 1) line 1, at end of line [Tue Aug 21 19:57:32 2001] (eval 1): (Do you need to predeclare Car +p::longme s?) [Tue Aug 21 19:57:32 2001] (eval 1): Array found where operator expect +ed at (ev l 1) line 2, at end of line [Tue Aug 21 19:57:32 2001] (eval 1): (Do you need to predeclare Car +p::shortm ss?) [Tue Aug 21 19:57:32 2001] (eval 1): Array found where operator expect +ed at (ev l 1) line 3, at end of line [Tue Aug 21 19:57:32 2001] (eval 1): (Do you need to predeclare Car +p::shortm ss?) [Tue Aug 21 19:57:32 2001] (eval 1): Array found where operator expect +ed at (ev l 1) line 4, at end of line [Tue Aug 21 19:57:32 2001] (eval 1): (Do you need to predeclare Car +p::longme s?) [Tue Aug 21 19:57:32 2001] Subroutine import redefined at C:\ +PERL\lib/ GI/ line 185. [Tue Aug 21 19:57:32 2001] Subroutine realwarn redefined at C +:\PERL\li /CGI/ line 198. Undefined subroutine &Carp::longmess called at C:\PERL\lib/ lin +e 296.
heres the code that goes with it.
#!/usr/bin/perl -w print "Content-type:text/html\n\n"; use CGI::Carp('fatalsToBrowser'); use strict; use warnings; print "Content-type:text/html\n\n"; @pages=(); @filenames=(); @titles=(); @headings=(); @stuff=(); open(PAGES, "<pages.txt"); while(<PAGES>) { push(@pages, $_) } close(PAGES); foreach $_ (@pages) { if (m/^\*\*\*\*filename.ext\*\*\*\*/) { push(@xfilenames, $_) } elsif (m/^\*\*\*\*title\*\*\*\*/) { push(@xtitles, $_) } elsif (m/^\*\*\*\*heading\*\*\*\*/) { push(@xheadings, $_) } else { push(@xstuff, $_) } } foreach $_ (@xfilenames) { s/^\*\*\*\*filename.ext\*\*\*\*//; chomp ($_); push(@filenames, $_); } foreach $_ (@xtitles) { s/^\*\*\*\*title\*\*\*\*//; chomp ($_); push(@titles, $_); } foreach $_ (@xheadings) { s/^\*\*\*\*heading\*\*\*\*//; chomp ($_); push(@headings, $_); } $xstuff = join("", @xstuff); @stuff = $xstuff =~ /\*\*\*\*stuff\*\*\*\*(.*?)\*\*\*\*endstuff\*\*\*\ +*/sg; open(TEMPLATE, "<template.html"); while(<TEMPLATE>) { push(@xtemplate, $_) } close (TEMPLATE); $xtemplate = join("", @xtemplate); @template = $xtemplate =~ /^(.*?)\*{4}filename.ext\*{4}/sg; push (@template, $xtemplate =~ /\*{4}filename.ext\*{4}(.*?)\*{4}title\ +*{4}/sg); push (@template, $xtemplate =~ /\*{4}title\*{4}(.*?)\*{4}headings\*{4} +/sg); push (@template, $xtemplate =~ /\*{4}headings\*{4}(.*?)/sg); for ($i=0; $i <= (@filenames-1); $i++) { open(FILE, ">@filenames[$i]") or die; print FILE QQ($temlate[0] $title[$i] $template[1] $heading[$i] $te +mplate[2] $stuff[$i] $template[3]); close(FILE); } print <<EndHTML; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transisional//EN" ""> <html> <head> <title>create</title> </head> <body> EndHTML foreach (@filenames) { print "$a <p>Name:$_</p>"; } print "<hr />"; foreach (@titles) { print "<p>Titles:$_</p>"; } print "<hr />"; foreach (@headings) { print "<p>Headings:$_</p>"; } print "<hr />"; foreach (@stuff) { print "<p>stuff:$_</p>"; } print <<EndHTML; </body> </html> EndHTML

Replies are listed 'Best First'.
Re: compilation errors???
by E-Bitch (Pilgrim) on Aug 22, 2001 at 08:18 UTC
    Okay, guess I overstepped my bounds... that last comment was out of line. My apologies.

    I wasnt aware that the last statement in a block wasnt needed... ya learn something new everyday. ++cLive!

    Totally missed the scalar part (I should have known that).

    First observation: All of your arrays (and other variables, for that matter) need to be declared local using the 'my' keyword (i.e: my @pages; etc) if you are going to use strict.

    The second observation: for ($i=0; $i <= (@filenames-1); $i++) should probably read for ($i=0; $i <= ($#filenames-1); $i++)

    The third observation:
    while(<PAGES>) { push(@pages, $_) }

    should read:
    while(<PAGES>) { push(@pages, $_); #semi colon added }

    Not to sound callous, but try debugging your code before something is assumed to have gone wrong with the module... your errors may be causing something wierd to happen during compilation.

    Tempora Mutantur Nos et Mutamur in Illis
    "The Times are Changed Even as We are Changed in Them"
      You said:
      while(<PAGES>) { push(@pages, $_); #semi colon added }
      Perl doesn't care if there's a semicolon there. Generally it's OK not to have one at the end of a block.

      But I'd say that the error messages from Perl are a bit cryptic from time to time; for a newbie, it can be somewhat hard to figure out what went wrong.

      What you can do is to forget, first, that this is a CGI. Comment out the "use CGI::Carp" and put in instead

      use Carp; use diagnostics;
      and then run Perl in check-mode: perl -cw and look at the output. You'll get a moderately less cryptic output that starts:

      Scalar value @filenames[$i] better written as $filenames[$i] at +line 71 (#1) (W syntax) You've used an array slice (indicated by @) to select a single element of an array. Generally it's better to ask for a sc +alar value (indicated by $). The difference is that $foo[&bar] always behaves like a scalar, both when assigning to it and when evaluati +ng its argument, while @foo[&bar] behaves like a list when you assign to +it, and provides a list context to its subscript, which can do weird t +hings if you're expecting only one subscript. On the other hand, if you were actually hoping to treat the array element as a list, you need to look into how references work, beca +use Perl will not magically convert between scalars and lists for you. + See perlref. Possible unintended interpolation of @filenames in string at lin +e 71. Scalar found where operator expected at line 72, near "] $title" + (#2) (S) The Perl lexer knows whether to expect a term or an operator. + If it sees what it knows to be a term when it was expecting to see an operator, it gives you this warning. Usually it indicates that an operator or delimiter was omitted, such as a semicolon. Global symbol "@pages" requires explicit package name at line 11 +. Global symbol "@filenames" requires explicit package name at lin +e 12. Global symbol "@titles" requires explicit package name at line 1 +3.

      This should start you on your way to fixing the problem. The "Global symbol...requires explicit package name" can be cured by declaring your variables using my.

      In C one of the most common errors to make is an off-by-one error. If you use explicit for loops in Perl, you will make the same error just as often. This is a good reason to use foreach loops whenever possible.

      I mention this because your second observation has an off-by-one in it. The odds of an off-by-one can be reduced, though, by:

      foreach my $i (0..$#filenames) { # ... }
      since that removes an inequality that people may miswrite. An even cleaner solution is offered by tye at mapcar -- map for more than one list.
      re 2nd obv
      @array in scalar context is the number of elements in the array. $#array is the index of the last element. ie
      $#array = @array -1;
      My only observation here is that:
      for ($i=0; $i <@filenames; $i++)
      is a little 'cleaner'.
      re 3rd obv
      Doesn't have to, as it's the last statement in a coding block. But, it *is* a good habit to get into.
      re uncallous comment
      "try debugging your code" - perhaps you could spend an extra minute or two checking your answer before ranting :)

      cLive ;-)

      PS - blame any lette ommissions on my dodgy keyboad which will get eplaced soon...


      PPS - try removing first print statement (why is it there?). I suggest you move the second to just above your output line (print <<EndHTML;). Other notes...

      # For tidyness, change: \*\*\*\* # in your regexp, to: \*{4} # for sanity control, change open(PAGES, "<pages.txt"); # to open(PAGES, "<pages.txt") || die $!; # (and do the same for you other filehandle opens) # and I'm pretty sure that print FILE QQ($temlate[0] ... # should be print FILE qq($temlate[0] ...
      And, to finish, I strongly suggest you use
      If you want to loop through the whole array with the for loop, wouldn't you want to have $#filenames+1 instead? Usually it would be much easier just to use @filenames in scalar context like so:

      for(my $i=0;$i<@filenames;$i++){stuff...}

      Also, you don't need to have a semi-colon to finish a statement if a brace immediately follows which means I can do stuff like:
      sub foo{return reverse split//,shift} #no semi-colon :) my $i = foo("oof rab"); print $i;

      (to the root node)Just so I don't have to create another post, I noticed that some of your calls use arrays slices when what you want is array indexes. This means taht @array[-1] is different than $array[-1] and could possibly lead to problems.

      Hope I helped :)

      $_.=($=+(6<<1));print(chr(my$a=$_));$^H=$_+$_;$_=$^H; print chr($_-39); # Easy but its ok.
      Third case should be @pages = <PAGES>;

      T I M T O W T D I