in reply to Trying to do multiple while loops on the same input file

Is this behavior intentional? Yes. In Perl files work about the same way they work in most languages. You open a file and then you read from start to end. Once you are at the end you can't read anymore unless you perform a seek.

Should I have known this to begin with? Hard to say. Let's just say that it is good that you know it now.

Does this behavior serve any purpose or have any benefit? Yes. It encourages "one-pass" processing of files. In other words it is more efficient to only read a file once (start to end). Structuring your code so that you don't need to make multiple passes through a file will make your program consume less resources and will most likely make your program more efficient.

Replies are listed 'Best First'.
Re^2: Trying to do multiple while loops on the same input file
by elef (Friar) on Jun 01, 2011 at 14:17 UTC
    It encourages "one-pass" processing of files. In other words it is more efficient to only read a file once (start to end). Structuring your code so that you don't need to make multiple passes through a file will make your program consume less resources and will most likely make your program more efficient.

    Thanks. That makes some sense, but, honestly, I'd rather have perl treat coders as adults who can decide for themselves how many times they want to read their files. In this case, the file is about 50kB long. Even supposing that it's not left in memory between two reads, it can be read from my SSD again in a matter of milliseconds. Not a lot of time compared to the hours I spent looking to find out what's wrong, I think you'll agree.
    On a more general note, I'd expect the TTMWTDI ethos to extend to allowing such "dumb" multiple reads on a filehandle, maybe throwing a warning if strictures are on. As it is, perl just fails to execute the second while loop without throwing any warning whatsoever, and whichever way you look at it, that's not very coder-friendly.

      It is much less a Perl way of doing things and more of an OS way of doing things. Perl gives you the seek function to do exactly what you want. Operating systems are made to handle 1kB files and also handle 3gB files. For your particular problem everything can be stored in ram (and possibly in a cache). For other problems the whole file cannot be stored in RAM.

      I am sorry that you spent hours looking for the issue. Trust me when I say that learning how file reading works will help you no matter what language you are using. I personally do not know of a language that provides the functionality that you desire in the basic read(file).I can tell you that C, C++, C#, Java, Perl and Python all read files in a start to finish manner.

      Update: fixed small typo.

        I can tell you that C, C++, C#, Java, Perl and Python all read files in a start to finish manner.

        I guess you meant "once only" instead of start to finish. That's fair enough, but if a command is going to fail, perl might as well give me some information about it. When you try to read a filehandle that never even existed, you get an "unopened filehandle" error message. I don't see why you shouldn't get an error message about an "already read" or "expired", "inactive" filehandle or something to that effect instead of the command failing silently, which makes debugging a nightmare.

      Well, I think I have to agree with Perl on this one. Its behavior is consistent. Once you reach the end of the file, "$line = <INPUTFILE>" is false. False ending the first loop, and still false at the beginning of any additional loops. It doesn't fail anything, it just doesn't change anything magically between loops either.

      It sounds like you would like it to be false, and then next loop reset back to the beginning of the file? That does not seem consistent to me. You'll note that you can do anything you like with INPUTFILE inside your while loop, and what would you expect the while() to do then?

      There is no explicit or implied relationship between your loop and what your loop does internal to Perl. Nor should there be imo. That's entirely for your code to establish.

      --Dave