in reply to while (<FP>) conditionals

My only guess as to why it continues is because <FP> actually returns 0 and a newline character.

It does, and a string containing “0\n” is true, not false:

14:26 >perl -we "my $s = qq[0\n]; printf qq[%s\n], ($s ? 'true' : 'fal +se');" true 14:31 >

To see the special behaviour described by ++davido, you can set the $/ variable (the input record separator) to read 1 character at a time, and then try a C-style for-loop (which does not have the special behaviour):

#! perl use strict; use warnings; local $/ = \1; for ($_ = <DATA>; $_; $_ = <DATA>) { print "<$_>\n"; } __DATA__ 1 0 42

— the loop terminates on the 0. To get the desired behaviour, change it to:

for ($_ = <DATA>; defined $_; $_ = <DATA>)

and a little experimentation will show you that this is now equivalent to the special forms:

print "<$_>\n" for <DATA>;

and

print "<$_>\n" while <DATA>;

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^2: while (<FP>) conditionals
by jktstance (Novice) on Feb 05, 2014 at 14:46 UTC
    It does, thank you. I tried running your first test:
    perl -we "my $s = qq[0\n]; printf qq[%s\n], ($s ? 'true' : 'fal +se');
    All I ever got were the following errors:
    syntax error at -e line 1, near "my =" Search pattern not terminated or ternary operator parsed as search pat +tern at -e line 1.
    However, when I put it into a script and ran it, it worked fine. Also, your second test does not work for me:
    #! perl use strict; use warnings; local $/ = \1; for ($_ = <DATA>; $_; $_ = <DATA>) { print "<$_>\n"; } __DATA__ 1 0 42
    When I run it, I get the following:
    <1> < >
    But at this point, my question is answered. Now we're just toying around!
      When typing code on the command line, you often have to escape some characters depending on your system.
      For example, the error message shows that: my $s = got munged by your shell into my  = before it was passed to perl.
        Another reason we should not use one-liners in replies if the OS is not specified.
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
        I escaped the two $s instances with backslashes and it worked fine. I'm still not sure why %s didn't need to be escaped. As you can probably tell, I'm not too well versed in the linux shell either...
      Also, your second test does not work for me ... When I run it, I get the following:

      But that’s exactly what you should get! local $/ = \1; makes the diamond operator read one character at a time. The first character is 1, which is printed. The second character is a newline, which is also printed (I put the angle brackets in to show that a new line has been printed). The third character is 0, and because the C-style for-loop is not magic, this is “false” and the loop terminates without printing anything more.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        OK, yes, I skipped over the 1-character point. It's actually only printing two things). Thanks, all straight now!