develooper Front page | perl.beginners | Postings from November 2022

Re: change one line in a large fine

Thread Previous | Thread Next
From:
Kang-min Liu
Date:
November 21, 2022 00:56
Subject:
Re: change one line in a large fine
Message ID:
86leo5yvl2.fsf@gugod.org

support@openmbox.net writes:

> please see this ops:
>
> $ echo -n 0 > 1.txt
>
> 1.txt has only one line without eof.
>
> but the script below still got true for matching 0.
>
> $ cat test.pl
> use strict;
>
> open HD,"1.txt" or die $!;
> while(<HD>){
>   print "hi";
> }
>
>
> which will print hi.
>
> can you help further?
>

I see -- so it's really about how readline operator (<FH>) works, or how
it works within a while loop. I'm not sure if I could explain it better
than quoting some documentation.

Indeed the readline operator returns the line and may set $_ as side-effect,
but when being tested in `while` -- and only in `while` -- perl
compiler does something extra and put an `defined` operator in there.

If you follow link in the documentation of readline [1] to "perlop: I/O
Operatorns" [2], you'll find this statement saying:

    Thus the following lines are equivalent:

        while (defined($_ = <STDIN>)) { print; }
        while ($_ = <STDIN>) { print; }
        while (<STDIN>) { print; }
        for (;<STDIN>;) { print; }
        print while defined($_ = <STDIN>);
        print while ($_ = <STDIN>);
        print while <STDIN>;

[1]: https://perldoc.perl.org/functions/readline
[2]: https://perldoc.perl.org/perlop#I%2FO-Operators

And the paragraph right before them contains some text describing the
same thing.

Such effect may be verified by compiling test.pl with -MO=Deparse:

  # perl -MO=Deparse test.pl
  use strict;
  die $! unless open HD, '1.txt';
  while (defined($_ = readline HD)) {
      print 'Hi';
  }
  test.pl syntax OK

You could see that <HD> is compiled to be "readline", and an extra
"defined" operator appears.

(See `perldoc B::Deparse` for more about -MO=Deparse)

You could furthermore play with it and see that no that extra "defined"
operator would be added to `if (<FH>)`, `unless (<FH>)`, `until (<FH>)`,
or when the while-condition is a bit more complicated (for
example: `while(! <FH>)`). This is a special case only for `while (<FH>)`

I guess this is made special to make it convenient for iterating through
the entire file line by line. Otherwise when line values are false-y by
chance, the loop ends early and mostly likely that'll be a surprise.

--
Cheers,
Kang-min Liu

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About