in reply to Re: Re: To Kill a Meme: while(defined($line = <>))
in thread To Kill a Meme: while(defined($line = <>))

I mostly agree with that except that I think it does lead to mistakes. Not coding mistakes, but conceptual mistakes. When it is coded explicitly, it seems to indicate that it is necessary for a common case.
Well, generally, the defined test is necessary. The "common" case is the exception where Perl is providing the short-cut. If there is any danger, it's that people get used to writing while ($line = <>), and think that they can also write: while ($cond and $line = <>) or $line = <>; while ($line) {.... ; $line = <>}.

Now, I don't think the danger is anything to worry about, but I've seen cases where the defined() test was missing where it should have been.

Now, I'd be really interested in hearing what you think is the common case, and where people get it wrong by using defined ($line = <>).

Abigail

Replies are listed 'Best First'.
Re: Re: To Kill a Meme: while(defined($line = <>))
by sauoq (Abbot) on Nov 03, 2003 at 10:54 UTC
    Now, I'd be really interested in hearing what you think is the common case, and where people get it wrong by using defined ($line = <>).

    The most common case is reading a text file which ends with a newline. And doing so without changing $/.

    What people get wrong is that they tend to think they need to check defined() because of blank lines. In other words, they get the mistaken impression that a scalar can contain a newline and be false.

    -sauoq
    "My two cents aren't worth a dime.";
    
      What people get wrong is that they tend to think they need to check defined() because of blank lines.

      Really? I've never encountered people thinking that. Why do you think people think this way? Have you ever seen code where people do:

      while ($line = <>) { ... }
      and expect it to read in just one paragraph, and not the entire file?

      Having said that, assuming you are right, it would be better to teach them the proper meaning of defined, instead of discouraging them not to used 'defined'.

      Abigail

Re: Re: To Kill a Meme: while(defined($line = <>))
by sauoq (Abbot) on Nov 03, 2003 at 11:09 UTC
    I've seen cases where the defined() test was missing where it should have been.

    I'm curious by what criteria you judge that it "should have been." Do you mean that it should be there as a matter of good defensive programming style? Or was there a real likelihood that an error would have resulted eventually? And, if so, what error?

    -sauoq
    "My two cents aren't worth a dime.";
    
      I'm curious by what criteria you judge that it "should have been." Do you mean that it should be there as a matter of good defensive programming style?

      Nothing to do with style, but with correctness. Stuff like:

      while (($line = <>) && $line =~ /\S/) { ... } while (($line1 = <>) && ($line2 = <>)) { ... }
      Also, the standard way of translating a while to a for(;;) loop won't work:
      for (;$line = <>;) { ... }
      And even:
      next unless $line = <>;

      They are all cases where a defined test should be used, because otherwise you may get unwanted effects.

      Abigail