Usage of defined with Filehandle and while Loop

后端 未结 3 484
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-20 20:30

While reading a book on advanced Perl programming(1), I came across this code:

while (defined($s = <>)) {
    ...

Is there

3条回答
  •  青春惊慌失措
    2021-01-20 21:19

    Say you have the following file

    4
    3
    2
    1
    0
    

    ( represents a line feed. Note the lack of newline on the last line.)

    Say you use the code

    while ($s = <>) {
       chomp;
       say $s;
    }
    

    If Perl didn't do anything magical, the output would be

    4
    3
    2
    1
    

    Note the lack of 0, since the string 0 is false. defined is needed in the unlikely case that

    • You have a non-standard text file (missing trailing newline).
    • The last line of the file consists of a single ASCII zero (0x30).

    BUT WAIT A MINUTE! If you actually ran the above code with the above data, you would see 0 printed! What many don't know is that Perl automagically translates

    while ($s = <>) {
    

    to

    while (defined($s = <>)) {
    

    as seen here:

    $ perl -MO=Deparse -e'while($s=) {}'
    while (defined($s = )) {
        ();
    }
    __DATA__
    -e syntax OK
    

    So you technically don't even need to specify defined in this very specific circumstance.

    That said, I can't blame someone for being explicit instead of relying on Perl automagically modifying their code. After all, Perl is (necessarily) quite specific as to which code sequences it will change. Note the lack of defined in the following even though it's supposedly equivalent code:

    $ perl -MO=Deparse -e'while((), $s=) {}'
    while ((), $s = ) {
        ();
    }
    __DATA__
    -e syntax OK
    

提交回复
热议问题