I/O

eof#

Test a filehandle for end-of-file.

eof reports whether the next read on a filehandle will return end-of-file. The three call forms look similar but mean different things: eof FILEHANDLE asks about a specific handle, bare eof asks about the handle most recently read from, and eof() with empty parentheses asks about the virtual ARGV stream fed by <>. The forms are not interchangeable — picking the wrong one is the classic bug with this built-in.

Synopsis#

eof FILEHANDLE
eof()
eof

What you get back#

1 if the next read on the handle would return end-of-file, or if the handle is not open. 0 otherwise. eof never blocks waiting for more input on a regular file, but on a pipe or terminal it may have to read and push back one character to decide — see Edge cases.

Global state it touches#

  • ARGV — the magical filehandle backing the <> operator. eof() examines and may advance it; eof inside a while (<>) loop queries it indirectly.

  • @ARGV — the list of file names <> iterates over. eof() called before <> has been used triggers @ARGV inspection and, if empty, arranges for STDIN to be read.

  • $. — the current input line number, attached to the handle eof queries. Not written by eof itself, but relevant in the idioms below where close ARGV resets it at file boundaries.

The three forms, spelled out#

eof FILEHANDLE — asks about that one handle. FILEHANDLE may be a bareword, a scalar holding a handle, or an expression evaluating to one. Returns true for a closed or never-opened handle.

eof (no parentheses, no argument) — asks about the last file read. Inside a while (<>) { ... } loop this means “the current ARGV file” — the physical file currently being streamed, not the whole <> sequence. eof becomes true at every file boundary, once per input file.

eof() (empty parentheses) — asks about the <> stream as a whole. It becomes true only at the end of the last file in @ARGV. If <> has not been used yet, eof() will examine @ARGV, fall back to STDIN when @ARGV is empty, and may actually open the first file to answer the question.

Bare eof and eof() look almost identical and do completely different things. The parentheses matter.

Examples#

Check a specific handle before the next read:

open my $fh, "<", "data.txt" or die $!;
while (not eof $fh) {
    my $line = <$fh>;
    # process $line
}
close $fh;

The classic while (<>) idiom, resetting $. at each file boundary. Bare eof (no parens) is what you want here — it fires once per input file:

while (<>) {
    next if /^\s*#/;
    print "$.\t$_";
} continue {
    close ARGV if eof;        # not eof() — resets $. per file
}

Insert a marker before the last line of the last file. eof() with parentheses catches the end of the entire <> stream, not each file:

while (<>) {
    if (eof()) {
        print "--------------\n";
    }
    print;
    last if eof();            # needed when reading from a terminal
}

Guard against a closed handle. eof on a closed or never-opened handle returns true without warning:

my $fh;                       # never opened
if (eof $fh) {
    warn "handle not ready";
}

Edge cases#

  • eof before any read returns false, not true. Bare eof with no prior read has no “last file read” to refer to and Perl treats it as false. Writing if (eof) { ... } at the top of a program does not mean “if there is no input” — use eof() for that.

  • eof() before <> is used has side effects. It examines @ARGV, and if @ARGV is empty it arranges for <> to read from STDIN. A stray eof() at program start can therefore silently bind the program to STDIN.

  • eof() after <> has exhausted its input assumes you are starting another @ARGV pass. If @ARGV is empty at that point, the next <> reads STDIN. This is usually not what you want; set @ARGV explicitly or test the bare-eof form instead.

  • eof on a terminal consumes a character. The implementation reads one byte and ungetcs it to tell whether more input exists. On terminals the pushback may not survive after end-of-file is reached — do not call eof FH on a terminal after you have already hit EOF there, or the handle can lose its end-of-file condition.

  • Closed or never-opened handleeof FILEHANDLE returns true. There is no way to distinguish “closed” from “at EOF” using eof alone; check fileno or track the open state yourself if that matters.

  • eof(ARGV) equals bare eof inside while (<>). Both query the current ARGV file. Prefer bare eof for brevity and to make the parenthesised eof() form visually distinct.

  • You rarely need eof at all. The input operators return undef at end-of-file, so while (my $line = <$fh>) { ... } and while (<>) { ... } handle termination without any eof test. Reach for eof only when you need to act at the boundary — last line, per-file reset, final-file marker.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • readline — read a line from a handle; returns undef at end-of-file, which replaces most uses of eof

  • read — block read of a fixed byte count; returns 0 at end-of-file

  • getc — read a single character; returns undef at end-of-file

  • close — close a handle; the common partner of eof in the close ARGV if eof per-file-reset idiom

  • ARGV — the magical handle fed by <> that eof and eof() query