Beefy Boxes and Bandwidth Generously Provided by pair Networks kudra
The stupid question is the question not asked
 
PerlMonks  

Why is the error thrown from close(FH) when the error is the missing <> on while(FH)?

by techgrrl (Acolyte)
on Feb 01, 2013 at 02:34 UTC ( #1016425=perlquestion: print w/ replies, xml ) Need Help??
techgrrl has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow monks.

I solved my problem, but I am trying to understand the error message that preceded it, that I might gain wisdom from the experience.

When I leave off the <> operator on the while(<KNOWN_HOSTS> loop on line 83 in the below code snippet, the error is thrown from the close on line 92, instead of the while on line 83.

My question is: Why is the error not thrown from the while on 83?

while (KNOWN_HOSTS) { # this is line 83 $inline = $_; if (isOneOf($inline,@contexts)) { next; } else { print; } } close(KNOWN_HOSTS); # this is line 92
user@localhost ~$ ./strip_keys.pl -u user my-device.config
Bareword "KNOWN_HOSTS" not allowed while "strict subs" in use at ./strip_keys.pl line 92.
Execution of ./strip_keys.pl aborted due to compilation errors.

Comment on Why is the error thrown from close(FH) when the error is the missing <> on while(FH)?
Download Code
Re: Why is the error thrown from close(FH) when the error is the missing <> on while(FH)?
by toolic (Chancellor) on Feb 01, 2013 at 02:45 UTC

      Thanks, but do bear in mind, I already know the error, and I fixed it.

      This question has nothing to do with the syntax error, it is about trying to understand a diagnostic message, in order to gain wisdom.

      I ran deparse, and it printed my code prepended with the word LINE: and followed it with a diagnostic saying the syntax was OK.

      $ perl -MO=Deparse -p strip_keys.pl 
      
      LINE: while (defined($_ = <ARGV>)) { use warnings; use strict 'refs'; our($opt_h, $opt_k, $opt_u); my($inline, $device, $config, $file, $context, @contexts); use Getopt::Long; &help unless GetOptions 'h', \$opt_h, 'u:s', \$opt_u, 'k:s', \$opt +_k, 'device:s', \$device; &help if $opt_h; etc. continue { print $_; }
      strip_keys.pl syntax OK
      
Re: Why is the error thrown from close(FH) when the error is the missing <> on while(FH)?
by 7stud (Deacon) on Feb 01, 2013 at 02:54 UTC
    How did you get that far:
    Global symbol "$inline" requires explicit package name at 2.pl line 6. Global symbol "$inline" requires explicit package name at 2.pl line 7. Global symbol "@contexts" requires explicit package name at 2.pl line +7. Bareword "KNOWN_HOSTS" not allowed while "strict subs" in use at 2.pl +line 14. Execution of 2.pl aborted due to compilation errors.

    Next, is it your understanding that a while loop conditional can only be the line input operator(<>)?

      Greetings

      It is a code fragment, not a full program.

      In order to actually create an executable script I would need to provide multiple files and quite a bit more code. I can do that if requested, but I was hoping that since the reason the error was thrown was given (the missing double diamond <> operator) that someone could look at this and help me understand why is was thrown from the close(FH) instead of the while(FH) where the error is.

      I don't think duplicating the error would tell you anything the sample does not already tell you, but I could be wrong I suppose.

      Cheers,

      TechGrrl

Re: Why is the error thrown from close(FH) when the error is the missing <> on while(FH)?
by Anonymous Monk on Feb 01, 2013 at 03:28 UTC

    Given the the file handle is actually is, error is coming from the condition for while ...

    # cat p.pl ; perl p.pl use strict; open FH , '<' , $0 or die "open failed: $!"; while( FH ) { last; } close FH or die "close failed: $!"; __END__ Bareword "FH" not allowed while "strict subs" in use at p.pl line 11. Execution of p.pl aborted due to compilation errors

    ... despite the line number reported. open & close can deal with a bareword file handle but not loop condition.

Re: Why is the error thrown from close(FH) when the error is the missing <> on while(FH)?
by 7stud (Deacon) on Feb 01, 2013 at 06:07 UTC
    This doesn't produce an error:
    my $fname = 'data.txt'; open FH, "<", $fname or die "Couldn't open $fname: $!"; while(FH) { print "hello\n"; }
    Nor does this:
    while(FH) { print "hello\n"; }

    According to "Perl Best Practices", p. 65:

    In Perl, any identifier that the compiler doesn't recognize as a subroutine (or as package name or filehandle or label or builtin function) is treated as an unquoted character string:

    $greeting = Hello . World; print $greeting, "\n"; #Prints: HelloWorld
    I'm not sure why there are parentheses around "or package name or filehandle..." because the section is not about subroutines. And it should say, "...is treated as a string".

      You missed to read the error message in OP, repeated below for you, that has the clue ...

      user@localhost ~$ ./strip_keys.pl -u user my-device.config Bareword "KNOWN_HOSTS" not allowed while "strict subs" in use at ./str +ip_keys.pl line 92. Execution of ./strip_keys.pl aborted due to compilation errors.

      ... run your own 1st snippet of code with "use strict;" and be able to reproduce the fatal error similar to above. Also, read up on "constant" pragma and "bareword".

        No, I saw it eventually--I was still editing my post when you posted. :)
Re: Why is the error thrown from close(FH) when the error is the missing <> on while(FH)?
by kcott (Abbot) on Feb 01, 2013 at 07:55 UTC

    G'day techgrrl,

    Welcome to the monastery.

    Perl is reading up to the statement terminator (semicolon) on line 92 before deciding that it's found a disallowed bareword. The fact that line 92 also contains KNOWN_HOSTS is something of a red herring. Consider:

    $ perl -Mstrict -E ' while (KNOWN_HOSTS) { say "Hello"; last; } close KNOWN_HOSTS; ' Bareword "KNOWN_HOSTS" not allowed while "strict subs" in use at -e li +ne 6. Execution of -e aborted due to compilation errors.

    versus

    $ perl -Mstrict -E ' while (KNOWN_HOSTS) { say "Hello"; last; } say "Bye"; ' Bareword "KNOWN_HOSTS" not allowed while "strict subs" in use at -e li +ne 6. Execution of -e aborted due to compilation errors.

    Where code extends over multiple lines, Perl will typically report an error at the end of the multi-line code. You need to bear this in mind when debugging - you can have instances where you need to backtrack many lines to find the line where the actual problem has occurred.

    If you're wondering why Perl didn't see the closing brace as the end of the statement, consider:

    $ perl -Mstrict -E ' while (KNOWN_HOSTS) { say "Hello"; last; } continue { 1; } ' Bareword "KNOWN_HOSTS" not allowed while "strict subs" in use at -e li +ne 8. Execution of -e aborted due to compilation errors.

    Aside: where you used perl -MO=Deparse -p ... above, I'm wondering if you meant perl -MO=Deparse,-p ..., i.e. s/ -p/,-p/.

    -- Ken

      Thank you Ken!

      That was the source of my confusion. To summarize the answer: PERL reports multi-line errors at the end, and the close(FH) at the end of the piece of code was a red-herring.

      That was not behavior I was expecting.

      Have a great day!

      TechGrrl
Re: Why is the error thrown from close(FH) when the error is the missing <> on while(FH)? ( line number mismatch, look above, look before )(Bareword found in conditional)
by Anonymous Monk on Feb 01, 2013 at 09:03 UTC

      Those are some great links! The first one has some good examples of this occurring in other contexts. I have a lot of reading to do.

      Thanks for taking the time to include those references!

      TechGrrl

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2014-04-20 02:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls