Re: Requesting regular expression help



On Sun, 28 Feb 2010 09:55:20 -0600, Tad McClellan <tadmc@xxxxxxxxxxxxxx> wrote:

sln@xxxxxxxxxxxxxxx <sln@xxxxxxxxxxxxxxx> wrote:
On Sat, 27 Feb 2010 12:33:34 +0100, "Peter J. Holzer" <hjp-usenet2@xxxxxx> wrote:


while (<FH>)
is actually a shorthand for
while (defined($_ = <FH>))
so even if the last line of a file is "0" without a trailing newline,
the loop will still be executed.

while (($bar = <DATA>) && $flag )
produces traditional behavior (no shortcut), with a nice
little unwanted message:
Value of <HANDLE> construct can be "0"; test with defined() at ..


The warning is wanted for the reason already given, this loop
might exit earlier than intended (because $flag will not be
evaluated if $bar eq '0').

Thats not why the warning is there. The same warning shows up with
if ($bar=<DATA>) # a conditional

which has no $flag and no shorthand. Perl has to make that distinction,
when asigning to a scalar from <> and used in a conditional, that '0'
is a falsehood. Its no different then
$bar=<DATA>; # not a conditional and no message
if ($bar) # same thing

I'm testing for the truth of $bar. As you mentioned, there
are more than one falsehood, undefined, '', '0', empty list, etc,
everything else is true.

if (defined($bar)) only tests for one truth - is it defined,
but if ($bar) can still be false even though its defined and
with the <> construct, it can only be '0' that makes it false.

So, its more confusing than not when Perl goes behind your back
with this shortcut within a conditional and only within a
while loop, not other constructs. And only then if there
is the single term conditional as a result of an assignment,
ie: $bar=<FH> or just <> ($_=<FH>).

The result is that Perl alters the conditional, significantly,
to get around '0' as a natural *false* condition.

I would rather have it all one way or all the other as far as
conditionals are concerned.

Personally, I always write mine as:
while (defined($bar=<FH>) {}
just incase I want to come back later and add a term to the conditional:
while ($flag && defined($bar=<FH>) {}


Instead, the distinction could be confusing:

while( $bar=<FH> )
{
if (!$bar) {
print "why am I still in this loop\n";
if (defined $bar) {
print "because i'm defined?\n";
if ($bar eq '0') {
print "'$bar' was there any doubt?\n";
}
}
}
...
last if !($bar=<FH>);
...
$bar = <FH>;
last if !bar;
...
}
# or
while( $flag && $bar=<FH> )
{}

The docs don't really say why the shorthand is dropped if
using multiple terms in the conditional. I'm not so sure why
it is done this way, the shorhand, the rules, what the rules are, etc..
Maybe its to get people guessing and to use Deparse.

-sln
.