New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
eof() Returns True Incorrectly Before Input Read. #904
Comments
From ralph@inputplus.demon.co.ukeof() (the <> magic version) returns true if no attempt to read from <> A simple test case (that doesn't illustrate why I want to do this) is #! /usr/local/bin/perl -w use strict; my $l; Here's it running; I've added comments. % ./p The behaviour once something has been read using <> is fine; it's I'm trying this now on a fairly old version, 5.00404, but I've just Ralph. Site configuration information for perl 5.00404: Configured by root at Thu Sep 10 02:15:30 EDT 1998. Summary of my perl5 (5.0 patchlevel 4 subversion 4) configuration: |
From [Unknown Contact. See original ticket]On Tue, Nov 30, 1999 at 06:23:53PM +0000, Ralph Corderoy wrote:
I'd say this is working as documented. To quote the documentation on Returns 1 if the next read on FILEHANDLE will return end of file, No file handle is open at that point in your program (because we The documentation on eof() goes on to say (Note that this function actually reads a character and then and Practical hint: you almost never need to use C<eof> in Perl, Hope this helps, -Scott |
From [Unknown Contact. See original ticket]duff@cbi.tamucc.edu writes:
This needs to be corrected. Is "false (undefined) values" a better wording? Ilya |
From [Unknown Contact. See original ticket]Ilya Zakharevich <ilya@math.ohio-state.edu> wrote
To avoid confusion, I think all mention of "false" needs to be Mike Guy Inline Patch--- ./pod/perlfunc.pod.orig Thu Nov 18 19:10:49 1999
+++ ./pod/perlfunc.pod Wed Dec 1 15:32:51 1999
@@ -1199,7 +1199,7 @@
}
Practical hint: you almost never need to use C<eof> in Perl, because the
-input operators return false values when they run out of data, or if there
+input operators return C<undef> when they run out of data, or if there
was an error.
=item eval EXPR
End of patch |
From [Unknown Contact. See original ticket]duff@cbi.tamucc.edu wrote:
Hi, I agree it's as documented but since eof() is testing the magic <> And while I know it almost never necessary to use eof I think I have an #! /usr/local/bin/perl -w use strict; my $p = '.' x 0x20000; $p = ''; while (!eof()) { # just an example; real life is more complex! Regardless of @ARGV only `post while' is printed because, as documented, But, I thought eof was meant to indicate that the next read from the The non-<> version of eof works fine in this respect. $ perl -we 'close F; eof F or die' But shouldn't eof(), associated as it is with the magic <>, have a Ralph. |
From @tamiasOn Wed, Dec 01, 1999 at 05:51:34PM +0000, ralph@inputplus.demon.co.uk wrote:
Have you tried do { } until eof() ? That may allow you to do what you want. Ronald |
From @TimToadyralph@inputplus.demon.co.uk writes: Makes sense to me, as much as eof() ever makes sense. Larry |
From [Unknown Contact. See original ticket]On Wed, Dec 01, 1999 at 05:51:34PM +0000, ralph@inputplus.demon.co.uk wrote:
You don't *have* to use <> you know. It's a short cut for those Nothing is stopping you from treating each thing in @ARGV as a file
^^^^^^^^^^^^^^^^^^^^^^^^^^^
while (1) { I don't see the problem. -Scott |
From [Unknown Contact. See original ticket]On Wed, Dec 01, 1999 at 04:06:58PM -0600, duff@cbi.tamucc.edu wrote:
Preallocate buffer to avoid incremental growth. Ilya |
From @vanstynIn <199912011751.RAA121642@cm01.ess>, ralph@inputplus.demon.co.uk writes: No, it says that you are currently at the end of the current file, or When reading from <> in particular, there may be several files to read I think it would be a bad idea to change eof() in the way you suggest. Hugo |
From [Unknown Contact. See original ticket]Hi Hugo,
Only when reading from <>?
No, that's eof. I'm talking about eof(). Ralph. |
From [Unknown Contact. See original ticket]
No, but if, as I stated, I want the magical behaviour of <> I have to
Take the time to study my example again. ;-) $ perl -we '$_ = "x"; substr($_, length, 0) = <>' </dev/null Ralph. |
From [Unknown Contact. See original ticket]
Hi, thanks for the suggestion but I want to avoid a <> that hits the Ralph. |
From @gsarOn Tue, 30 Nov 1999 18:23:53 GMT, Ralph Corderoy wrote:
Despite what the documentation claims, it turns out that eof() The attached patch fixes both problems and appears to work on your Sarathy Inline Patch-----------------------------------8<-----------------------------------
Change 4642 by gsar@auger on 1999/12/04 21:11:51
make eof() open ARGV if it isn't open already; also fixes bug
where eof() would operate on any last-read filehandle, not
just ARGV
Affected files ...
... //depot/perl/pp_sys.c#131 edit
Differences ...
==== //depot/perl/pp_sys.c#131 (text) ====
Index: perl/pp_sys.c
--- perl/pp_sys.c.~1~ Sat Dec 4 13:15:57 1999
+++ perl/pp_sys.c Sat Dec 4 13:15:57 1999
@@ -1703,10 +1703,28 @@
GV *gv;
MAGIC *mg;
- if (MAXARG <= 0)
- gv = PL_last_in_gv;
+ if (MAXARG <= 0) {
+ if (PL_op->op_flags & OPf_SPECIAL) { /* eof() */
+ IO *io;
+ gv = PL_last_in_gv = PL_argvgv;
+ io = GvIO(gv);
+ if (io && !IoIFP(io)) {
+ if ((IoFLAGS(io) & IOf_START) && av_len(GvAVn(gv)) < 0) {
+ IoLINES(io) = 0;
+ IoFLAGS(io) &= ~IOf_START;
+ do_open(gv, "-", 1, FALSE, O_RDONLY, 0, Nullfp);
+ sv_setpvn(GvSV(gv), "-", 1);
+ SvSETMAGIC(GvSV(gv));
+ }
+ else if (!nextargv(gv))
+ RETPUSHYES;
+ }
+ }
+ else
+ gv = PL_last_in_gv; /* eof */
+ }
else
- gv = PL_last_in_gv = (GV*)POPs;
+ gv = PL_last_in_gv = (GV*)POPs; /* eof(FH) */
if (gv && (mg = SvTIED_mg((SV*)gv, 'q'))) {
PUSHMARK(SP);
End of Patch. |
From [Unknown Contact. See original ticket]Hi, gsar@activestate.com wrote:
Just to let you know I am working on this and haven't slunk off I already had a patch to t/io/argv.t, some of which correctly failed, Your patch seems fine after an initial check. Should I also patch Ralph. |
From [Unknown Contact. See original ticket]Hi,
Below are three patches. Sorry if I haven't submitted them in the patch01.fixme justs add a FIXME comment to pp_getc because it is doing patch02.perlre.pod fixes some problems I happened to notice with patch03.eof_magic is the fix for ID 19991130.004. As well as the code Ralph. ======== 8< patch01.fixme ======== Inline Patchdiff -ruN perl5.005_62/pp_sys.c new/pp_sys.c
--- perl5.005_62/pp_sys.c Sat Oct 9 18:23:30 1999
+++ new/pp_sys.c Tue Dec 7 22:48:50 1999
@@ -1095,6 +1095,8 @@
gv = PL_stdingv;
else
gv = (GV*)POPs;
+ /* FIXME: why use argvgv? what situation can this occur under?
+ * it doesn't seem to be documented in perlfunc(1). */
if (!gv)
gv = PL_argvgv;
Inline Patchdiff -ruN perl5.005_62/pod/perlre.pod new/pod/perlre.pod
--- perl5.005_62/pod/perlre.pod Thu Oct 14 19:14:24 1999
+++ new/pod/perlre.pod Tue Dec 7 23:34:47 1999
@@ -121,7 +121,7 @@
This is usually 32766 on the most common platforms. The actual limit can
be seen in the error message generated by code such as this:
- $_ **= $_ , / {$_} / for 2 .. 42;
+ $_ **= $_ , / {$_} / for 2 .. 42;
By default, a quantified subpattern is "greedy", that is, it will match as
many times as possible (given a particular starting location) while still
@@ -191,7 +191,7 @@
The POSIX character class syntax
- [:class:]
+ [:class:]
is also available. The available classes and their backslash
equivalents (if available) are as follows:
@@ -214,7 +214,7 @@
Note that the C<[]> are part of the C<[::]> construct, not part of the whole
character class. For example:
- [01[:alpha:]%]
+ [01[:alpha:]%]
matches one, zero, any alphabetic character, and the percentage sign.
@@ -247,29 +247,27 @@
=item cntrl
- Any control character. Usually characters that don't produce
- output as such but instead control the terminal somehow:
- for example newline and backspace are control characters.
- All characters with ord() less than 32 are most often control
- classified as characters.
+Any control character. Usually characters that don't produce output as
+such but instead control the terminal somehow: for example newline and
+backspace are control characters. All characters with ord() less than
+32 are most often control classified as characters.
=item graph
- Any alphanumeric or punctuation character.
+Any alphanumeric or punctuation character.
=item print
- Any alphanumeric or punctuation character or space.
+Any alphanumeric or punctuation character or space.
=item punct
- Any punctuation character.
+Any punctuation character.
=item xdigit
- Any hexadecimal digit. Though this may feel silly
- (/0-9a-f/i would work just fine) it is included
- for completeness.
+Any hexadecimal digit. Though this may feel silly (/0-9a-f/i would
+work just fine) it is included for completeness.
=item
Inline Patchdiff -ruN cvs/pod/perlfunc.pod new/pod/perlfunc.pod
--- cvs/pod/perlfunc.pod Wed Oct 13 17:13:36 1999
+++ new/pod/perlfunc.pod Sun Dec 12 18:17:07 1999
@@ -1172,13 +1172,17 @@
C<eof(FILEHANDLE)> on it) after end-of-file is reached. File types such
as terminals may lose the end-of-file condition if you do.
-An C<eof> without an argument uses the last file read as argument.
-Using C<eof()> with empty parentheses is very different. It indicates
-the pseudo file formed of the files listed on the command line,
-i.e., C<eof()> is reasonable to use inside a C<while (E<lt>E<gt>)>
-loop to detect the end of only the last file. Use C<eof(ARGV)> or
-C<eof> without the parentheses to test I<each> file in a while
-(E<lt>E<gt>) loop. Examples:
+An C<eof> without an argument uses the last file read. Using C<eof()>
+with empty parentheses is very different. It refers to the pseudo file
+formed from the files listed on the command line and accessed via the
+C<E<lt>E<gt>> operator. Since C<E<lt>E<gt>> isn't explicitly opened,
+as a normal filehandle is, an C<eof()> before C<E<lt>E<gt>> has been
+used will cause C<@ARGV> to be examined to determine if input is
+available.
+
+In a C<while (E<lt>E<gt>)> loop, C<eof> or C<eof(ARGV)> can be used to
+detect the end of each file, C<eof()> will only detect the end of the
+last file. Examples:
# reset line numbering on each input file
while (<>) {
diff -ruN cvs/pod/perldelta.pod new/pod/perldelta.pod
--- cvs/pod/perldelta.pod Fri Oct 15 10:40:01 1999
+++ new/pod/perldelta.pod Tue Dec 7 23:15:00 1999
@@ -685,6 +685,12 @@
on C<OLD>. Formerly, it would have returned the data from the start
of the following disk block instead.
+=head2 eof() has the same old magic as <>
+
+C<eof()> would return true if no attempt to read from C<E<lt>E<gt>> had
+yet been made. C<eof()> has been changed to have a little magic of its
+own, it now opens the C<E<lt>E<gt>> files.
+
=head2 system(), backticks and pipe open now reflect exec() failure
On Unix and similar platforms, system(), qx() and open(FOO, "cmd |")
diff -ruN cvs/pp_sys.c new/pp_sys.c
--- cvs/pp_sys.c Tue Dec 14 14:04:02 1999
+++ new/pp_sys.c Tue Dec 7 22:48:50 1999
@@ -1697,10 +1697,15 @@
GV *gv;
MAGIC *mg;
- if (MAXARG <= 0)
- gv = PL_last_in_gv;
- else
- gv = PL_last_in_gv = (GV*)POPs;
+ if (MAXARG > 0)
+ PL_last_in_gv = (GV*)POPs;
+ else if (PL_op->op_flags & OPf_SPECIAL)
+ PL_last_in_gv = PL_argvgv;
+
+ if (!PL_last_in_gv)
+ PL_last_in_gv = PL_argvgv;
+
+ gv = PL_last_in_gv;
if (gv && (mg = SvTIED_mg((SV*)gv, 'q'))) {
PUSHMARK(SP);
diff -ruN cvs/doio.c new/doio.c
--- cvs/doio.c Wed Oct 6 04:20:25 1999
+++ new/doio.c Tue Dec 7 23:26:36 1999
@@ -785,6 +785,7 @@
{
dTHR;
register IO *io;
+ PerlIO *fp;
int ch;
io = GvIO(gv);
@@ -800,6 +801,29 @@
Perl_warner(aTHX_ WARN_IO, "Filehandle %s opened only for output",
SvPV_nolen(sv));
}
+
+ fp = IoIFP(io);
+ if (!fp) {
+ if (IoFLAGS(io) & IOf_ARGV) {
+ if (IoFLAGS(io) & IOf_START) {
+ IoFLAGS(io) &= ~IOf_START;
+ IoLINES(io) = 0;
+ if (av_len(GvAVn(PL_last_in_gv)) < 0) {
+ do_open(PL_last_in_gv,"-",1,FALSE,O_RDONLY,0,Nullfp);
+ sv_setpvn(GvSV(PL_last_in_gv), "-", 1);
+ SvSETMAGIC(GvSV(PL_last_in_gv));
+ fp = IoIFP(io);
+ goto have_fp;
+ }
+ }
+ fp = nextargv(PL_last_in_gv);
+ if (!fp) { /* Note: fp != IoIFP(io) */
+ do_close(PL_last_in_gv, FALSE); /* now it does*/
+ IoFLAGS(io) |= IOf_START;
+ }
+ }
+ }
+have_fp:
while (IoIFP(io)) {
diff -ruN cvs/t/io/argv.t new/t/io/argv.t
--- cvs/t/io/argv.t Tue Jul 20 18:18:12 1999
+++ new/t/io/argv.t Tue Dec 7 22:37:12 1999
@@ -1,6 +1,6 @@
#!./perl
-print "1..6\n";
+print "1..14\n";
open(try, '>Io.argv.tmp') || (die "Can't open temp file: $!");
print try "a line\n";
@@ -55,5 +55,37 @@
open(try, '<Io.argv.tmp') or die "Can't open temp file: $!";
print while <try>;
close try;
+undef $^I;
+
+eof try or print 'not ';
+print "ok 7\n";
+
+eof NEVEROPENED or print 'not ';
+print "ok 8\n";
+
+open STDIN, 'Io.argv.tmp' or die $!;
+@ARGV = ();
+!eof() or print 'not ';
+print "ok 9\n";
+
+<> eq "ok 6\n" or print 'not ';
+print "ok 10\n";
+
+open STDIN, '/dev/null' or die $!;
+@ARGV = ();
+eof() or print 'not ';
+print "ok 11\n";
+
+@ARGV = ('Io.argv.tmp');
+!eof() or print 'not ';
+print "ok 12\n";
+
+@ARGV = ('/dev/null', '/dev/null');
+!eof() or print 'not ';
+print "ok 13\n";
+
+close ARGV or die $!;
+eof() or print 'not ';
+print "ok 14\n";
END { unlink 'Io.argv.tmp', 'Io.argv.tmp.bak' } |
Migrated from rt.perl.org#1839 (status was 'resolved')
Searchable as RT1839$
The text was updated successfully, but these errors were encountered: