in reply to Re: Determining what line a filehandle is on
in thread Determining what line a filehandle is on

More specifically:
my $line = 0; my $file = "file.txt"; open (FILE, $file) || die "Could not open $file\n"; while (<FILE>) { print "I am on line ", ++$line, "\n"; } close (FILE);

Replies are listed 'Best First'.
Re: Re^2: Determining what line a filehandle is on
by John M. Dlugosz (Monsignor) on Jul 06, 2001 at 07:10 UTC
    "More specifically"? What's wrong with using $.?
      There's nothing "wrong" with using $. since it accurately represents the line number read of the last file-handle read. You can even track more than one file at the same time:
      open (A, "ls|"); open (B, "ls|"); while (<A>) { print "A: $. "; <B>;<B>; print "B: $. "; } close (A); close (B);
      Which returns the output:
      A: 1 B: 2 A: 2 B: 4 A: 3 B: 6 A: 4 B: 8 A: 5 B: 10
      However, $. is what I would call a "magical" Perl variable because it comes from nowhere and has no inherent meaning. With English, it is $INPUT_LINE_NUMBER, and with IO::Handle you can use the method input_line_number, but the $INPUT_LINE_NUMBER variable is still "magical", and the IO::Handle system just makes things more difficult to implement.

      "Magical" variables, or those that are effectively, though not intuitively, linked to another variable or action are certainly able to be used, but the issue I have with them is that to the average programmer, especially one not intimately familar with Perl, is that they don't make any sense. Using them on a quick hack is one thing, but using them on a program that might have to be maintained by others is a counterproductive form of obfuscation.
        Larry Wall compares $_, which is also magical, to the pronoun "it." Generalizing we can say that all magical variables of this kind are pronouns, e.g., "he", "she", "thou" etc.

        One of the great things about Perl is that Larry Wall when explaining it uses ideas from linguistics. Pronouns exist in all spoken languages that I know of for a reason. They avoid repeating obvious information in a way that reduces readability.

        It may be true that the "average" Perl programmer may not know all of the magical variables by heart, but he knows that an unusual short dollar sign symbol is a magical variable. Stripping the more arcane special variables out of Perl is like decreeing that from now on no one should use the word "thou" when speaking to others.

        "To every thing there is a season" (King Solomon/Pete Seeger/Crosby and McGuinn)

        matt brings up a good point back on the main thread, that $. will count correctly even when the special <> magic handle moves from file to file. Doing that yourself means testing eof in your loop too, and complicating things.

        Update:Well, it seems that $. doesn't reset on each file normally. You need to add a close ARGV if eof;statement inside the loop anyway!

        But, your argument is that the magic <> is obsure so you shouldn't use that either—with so much magic and subtlety, “to the average programmer, especially one not intimately familar with Perl, is that they don't make any sense.”

        But it does something so useful that would be a lot of code to do yourself! The program would be harder to figure out, and possibly buggy, if you did it yourself. And if all that code was put into a module and you got it down to a single function call, well, that's just what <> does in the first place.

        So, given the sentiment that obscure things can make it difficult for maintaniance, where do you draw the line? Answer: how easy is it to look up? If the obscure thing is some idiom spread over a few lines, and you don't know the name of it, how do you look it up anywhere? But a particular function call or special variable is easy to look up in the manual under that name. In the former case, always use a comment that could be as simple as naming the construct, e.g. "sort using the or-cache maneuver".

        —John

        I agree with the reply that the magical variables all have a recognisable form, so that a programmer might not know what $. or $] means, but knows it is one of those magical variables and can look it up.

        However, calling $input->input_line_number() is quite clear, and according to the docs, is a true method that works on the object called with, rather than doing something counterintuitive like input_record_separator() which is actually global.

        What do you mean by "makes things more difficult to implement"? You mean in general, or because this simple task is so small it's not with the overhead?

        —John