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

I'm writing this perl script, and when I compile it, i get an error that stats, "global symbol "$currentLine" requires explicit package name at ./filehandlers1.pl line 6." Another error is the same, except instead of "$currentLine", it is "$name". the program reads:.
!/usr/local/bin/perl print "Input file name: "; chomp ($infilename = <STDIN>); use strict; while ( defined($currentLine = <STDIN>) ) { if ($currentLine =~ /^ $name:/) { print $currentLine; } } close(IN) close(OUT)
..... I'm trying to read a line with the word "$name", there. and then i need to parse the last two elements from the line, made up of five rows, including the word name. Can some one let let me know why am I getting the error? and how would I go above solving the problem? Thanks Paav

Replies are listed 'Best First'.
Re: required explicit package error.
by btrott (Parson) on Jun 14, 2000 at 22:20 UTC
    You're getting these errors because you're using strict. But don't turn it off, because these errors are good! They're telling you that you should explicitly declare your variables as either package globals or lexicals (my).

    In your case, just use lexicals. Add this, before you start executing any code:

    my($currentLine, $name, $infilename);
    I've got to sort of question your program flow, though; you're looking for lines that begin with $name, right? But $name isn't defined--it has no value. So what are you trying to look for, then? Or are you trying to look for the string literal '$name', not the value of the variable name? If so, you should backslash the '$':
    if ($currentLine =~ /^ \$name:/) {
    Also, the first line of your script is a bit odd:
    !/usr/local/bin/perl
    Is this what you're really using? I don't think this will work. You should have:
    #!/usr/local/bin/perl
    and while you're at it, you should turn warnings on:
    #!/usr/local/bin/perl -w
      Btrott, Thanks a lot for your help. I still have a little problem I modified the program a little bit. It will be recieving information from a file. The program is supposed to parse the line with total in it. there is file rows there. i need to use the las two, the one with the total.
      ..... ..... .... .... .... ..... ..... .... .... .... total 1234 1234 5678 7894
      I need to use the the numbers "5678" and "7894", and graph them in excel everyday. The graph would be "day" vs "total". I hope this makes what I am trying to do a little easier to understand. Now my code reads...
      #!/usr/local/bin/perl -w my($currentLine, $name, $infilename); chomp ($infilename = "temp1.pl"); if ($ currentLine =~ /^ \$name:/) { print $currentLine; }
      Thanks alot, Paav
        It sounds like you just want a simple script to open a file, find the line that says "total", and report the last two rows of numbers. Here is some code to do this :
        #!/usr/local/bin/perl print "Input file name: "; $_ = <>; chop; open(INFILE, $_); while (<INFILE>) { if (m/total/) { s/^total\s[0-9]+\s[0-9]+\s([0-9]+)\s([0-9]+)$/$1 $2/; print; } } close INFILE;
        There are probably 3 things in this script that are non-intuitive to the budding Perl programmer :

        1) The use of $_
        2) The use of <>
        3) The use of regular expressions

        Here they are, demystified :

        1) $_ is the "default variable" when you don't supply any other variable name to a sub (such as chop and print in our example).

        2) <> abbreviates <STDIN>

        3) There are two regular expressions in this example, the first one is a matching regular expression (m/total/) which returns true if and only if the text "total" exists as a substring of $_

        The second regular expression is a search and replace regex.
        s/^total\s[0-9]+\s[0-9]+\s([0-9]+)\s([0-9]+)$/$1 $2/
        all it does is replace "^total\sA\sB\sC\sD$" with "C D" where ^ (caret) matches start of line, \s matches space, and A B C and D are numbers (1 or more digits). The use of the parenthesis following the first / provides Perl's regular expression engine the ability to do what is called "backreferencing" (using $1 and $2 after the second /).

        Let me know if that code works for you, and if there's anything else you'd like to do.

        -verbal </CODE>
        I don't know what you're doing there. It seems you've solved your initial problem, but that code isn't going to work correctly. Here's some code that may do what you want:
        #!/usr/local/bin/perl -w use strict; while (<>) { next if !/^total/; my @fields = split /\s+/; my($day, $total) = @fields[3,4]; ## Now graph the values or do whatever you ## want with them. ... ## This will exit the loop after it's seen ## the first "total" line. If you don't want ## to do this (if, for example, you'll have ## several "total" lines, each of which you ## want to graph), take out this line. last; }
        To be invoked as such:
        % foo.pl <filename>
Re: required explicit package error.
by jjhorner (Hermit) on Jun 14, 2000 at 22:35 UTC

    Some points to remember:

    • 'use strict' should be declared early.
    • I am not sure what you are doing, but based on the code above, you should make sure you declare your variables when using 'use strict'. You never declared $infilename, $currentLine, or $name.
    • Again, in the code above, you never opened IN or OUT.
    • Yet again, you never grabbed the user-entered text using the STDIN filehandle.
    • If you are just going to use the lines from IN in that 'while' loop, you could just:
      while (<IN>) { #do something } close IN;

    I hope this helps.

    J. J. Horner
    Linux, Perl, Apache, Stronghold, Unix
    jhorner@knoxlug.org http://www.knoxlug.org/
    
RE: required explicit package error.
by Ovid (Cardinal) on Jun 14, 2000 at 23:20 UTC
    Paav, it was a good question and I'm glad to see that people took the time to respond to it. For future reference, you may wish to be aware that you can format your code by wrapping it in <CODE></CODE> tags.
    !/usr/local/bin/perl print "Input file name: "; chomp ($infilename = <STDIN>); use strict; while ( defined($currentLine = <STDIN>) ) { if ($currentLine =~ /^ $name:/) { print $currentLine; } } close(IN); close(OUT);
    Such formatting makes code easier to read and guarantees a quicker response. It also guarantees that elements wrapped in <> won't be interpreted as HTML and ignored (which happened to the <STDIN> in your orginal post). For more information, check out the Site How To.

    Welcome to the Monastery!

    Cheers, Curtis