Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

I am geting an unhelpful error message. Not sure how to debug it.

by Socrates440 (Acolyte)
on Jun 15, 2012 at 03:22 UTC ( #976334=perlquestion: print w/ replies, xml ) Need Help??
Socrates440 has asked for the wisdom of the Perl Monks concerning the following question:

My latest assignment from my book (not a school assignmetn, I don't know if you have rules for that here. I am teaching myself perl.) asks me to create a program that can read another program line by line and reverse each line. I don't necessarily want the answer yet but I am getting a particularly unhelpful error that I can't debug. How do I fix it? The error is "syntax error at ./ioexperiment.plx line 7, near "foreach @line " Execution of ./ioexperiment.plx aborted due to compilation errors." The code is:
#!/usr/bin/perl -w use strict ; my ($a, @line) ; print "Please specify a file." ; chomp ($a = <STDIN>) ; open ($a) ; foreach @line ($a) { print reverse(@line); }

Comment on I am geting an unhelpful error message. Not sure how to debug it.
Download Code
Re: I am geting an unhelpful error message. Not sure how to debug it.
by Anonymous Monk on Jun 15, 2012 at 04:02 UTC

    Tutorials: Basic debugging checklist , brian's Guide to Solving Any Perl Problem

    Lets try one of these tips

    $ perl -c crates syntax error at crates line 7, near "foreach @line " crates had compilation errors. $ perl -Mdiagnostics -c crates syntax error at crates line 7, near "foreach @line " crates had compilation errors (#1) (F) Probably means you had a syntax error. Common reasons include +: A keyword is misspelled. A semicolon is missing. A comma is missing. An opening or closing parenthesis is missing. An opening or closing brace is missing. A closing quote is missing. Often there will be another error message associated with the synt +ax error giving more information. (Sometimes it helps to turn on -w. +) The error message itself often tells you where it was in the line +when it decided to give up. Sometimes the actual error is several toke +ns before this, because Perl is good at understanding random input. Occasionally the line number may be misleading, and once in a blue + moon the only way to figure out what's triggering the error is to call perl -c repeatedly, chopping away half the program each time to se +e if the error went away. Sort of the cybernetic version of S<20 questions>. Uncaught exception from user code: syntax error at crates line 7, near "foreach @line " crates had compilation errors. at crates line 10.

    Hmm, not so helpful. Ok, next check perlintro and perlsyn, specifically look for instances of foreach

    $ perldoc perlintro | grep foreach the more friendly list scanning "foreach" loop. foreach foreach (@array) { print $list[$_] foreach 0 .. $max; foreach my $key (keys %hash) { $ perldoc perlsyn | grep foreach foreach LIST The "foreach" modifier is an iterator: it executes the statement o +nce print "Hello $_!\n" foreach qw(world Dolly nurse); LABEL foreach VAR (LIST) BLOCK LABEL foreach VAR (LIST) BLOCK continue BLOCK The "foreach" loop iterates over a normal list value and sets the loop. This implicit localization occurs *only* in a "foreach" loop +. The "foreach" keyword is actually a synonym for the "for" keyword, + so you can use "foreach" for readability or "for" for brevity. (Or be +cause "foreach" loop index variable is an implicit alias for each item i +n the If any part of LIST is an array, "foreach" will get very confused +if you "foreach" probably won't do what you expect if VAR is a tied or ot +her foreach $item (split(/:[\\\n:]*/, $ENV{TERMCAP})) { Perl executes a "foreach" statement more rapidly than it would the Instead of using "given()", you can use a "foreach()" loop. For ex +ample, requires initialization, such as a subroutine or a "foreach" loop. + It

    ok, I don't see any "foreach @" uses, so checking http://perldoc.perl.org/perlsyn.html#Foreach-Loops is see lots of examples, but no "foreach @"

    That has to be the syntax error, changing that to "foreach $line ($a)"

    $ perl -c crates Global symbol "$line" requires explicit package name at crates line 7. crates had compilation errors.

    Right, that is strict catching a typo for me, I should write  foreach my $line ($a)

    $ perl -c crates crates syntax OK

    Great , syntax error resolved, next, some other things you should know

    perlvar#$a is a special variable, don't use it

    Don't use single argument form of open, use the 3 argument form

    using perlvar#@ARGV is better thanusing  <STDIN>

    $a is a filehandle, but you don't try to readline from it like you do from STDIN

    I highly recommend perlintro, http://learn.perl.org/books/beginning-perl/, http://perl-tutorial.org/, Modern Perl

      This is a spectacular post AnonyMonk. At first I wished I could have upvoted a name, but I like your style... a lot.

Re: I am geting an unhelpful error message. Not sure how to debug it.
by NetWallah (Abbot) on Jun 15, 2012 at 04:07 UTC
    The proper syntax for the "foreach" (aka "for") is:
    for my $a ( @line ) { .. Your code here }
    the "my $a" declares a locally scoped variable $a, that will be aliased to each element in @line.

    You also need to fix your OPEN statement - good practice requires it to use 3 parameters, and provide graceful exit in the event of failure.

    Onec you "open" successfully (and get a file handle), you need to use a mechanism to read each line of the file , using the file handle you obtained.
    All this is well documented in the fine manual, which includes examples.

    As a further comment on what you are attempting: when you read a file a line at a time, you normally place the data you get into a scalar.
    Your attempt to use @line to iterate over a single line will meet with (or possibly have already encountered) futility.
    Another hint: the "for" loop is not a good way to read all the records in a file - the more traditional way is to use a "while" loop.

                 I hope life isn't a big joke, because I don't get it.
                       -SNL

Re: I am geting an unhelpful error message. Not sure how to debug it.
by afoken (Parson) on Jun 15, 2012 at 04:08 UTC
    foreach @line ($a) {

    Lookup foreach in the documentation. If you use two variables with foreach, the first one must be a scalar, not an array.

    By the way: Your code either lacks

    or die "Can't open '$a': $!"

    after open or use autodie; after use strict;. And unless you have a very strangely named file on your filesystem, it will die. Lookup chomp.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Can I reverse each line if I store them in scalers? The exersize requires that I reverse each line before I print them. The only mechanism that I have for doing that only works with arrays (or so I believe.)
        Yes "reverse" works with scalars as well.(When maintained in a scalar context)

        It all depends on what you want to end-up with. Reverse on a scalar reverses the letters (Make sure you do this in a SCALAR context). On an array, it reverses the order of the elements.

        One way to achieve reversal would be to take the scalar, 'split' it into an array, and reverse the array.

                     I hope life isn't a big joke, because I don't get it.
                           -SNL

        perl -e "my $str='abcdef'; print scalar (reverse ($str));"
Re: I am geting an unhelpful error message. Not sure how to debug it.
by GrandFather (Cardinal) on Jun 18, 2012 at 00:22 UTC

    When learning is a good time to get into good habits. A few things have been pointed out by previous posters, but lets look at your whole sample and see where it can be improved.

    First, using strictures is highly recommended - well done. But it is more conventional now to use use warnings; instead of -w on the command line to enable warnings.

    Don't "pre-declare" variables. Declare them where you first need them and generally initialise them at the same time. Get into the habit of using sensible variable names. Short names are ok where they are only used in a small scope, but even then meaningful names can help a lot in understanding code. In particular avoid $a and $b because they have special meaning in the context of sort.

    Rolling these suggestions into those from previous replies and applying the scalar fix suggested elsewhere your sample code turns into something like:

    #!/usr/bin/perl -w use strict ; my ($a, @line) ; print "Please specify a file." ; chomp ($a = <STDIN>) ; open ($a) ; foreach @line ($a) { print reverse(@line); }

    Prints (given the script file as input):

    Please specify a file: noname.pl lrep/nib/rsu/!# ;tcirts esu ;sgninraw esu ;" :elif a yficeps esaelP" tnirp ;)>NIDTS< = emanelif$ ym(pmohc ;"n\!$ :emanelif$ nepo t'naC" eid ro emanelif$ ,'<' ,nIelif$ ym nepo { )>nIelif$< = enil$ ym( elihw ;)enil$(esrever ralacs tnirp }
    True laziness is hard work

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (7)
As of 2014-12-28 00:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls