Thanks! Learn something every day! (well, lots today). But what is going on here? What (under the covers) makes this a special case? Why is Perl wrapping $_=<> in defined($_ =<>)? Another convenience feature? And where else does this happen?
Here's my output with a slightly expanded print line checking both the value and the defined status and just to make sure there was no monkey business with the special variable $_ I changed it to $line - same result as you, of course. (I had to switch " and ' to keep the bash shell from trying to resolve $_):
$ perl -e'print 0' | perl -e'while ($line = <>) { print "\$line=<$lin
+e> \$line=<" . ($line ? "true" : "false") . "> defined=<" . (defined(
+$line) ? "true" : "false") . ">\n"};'
$line=<0> $line=<false> defined=<true>
It is also not anything special about the syntax $somevar = <> because I get the same result if I use readline(...):
$ perl -e'print 0' | perl -e'while ($line = readline(*STDIN)) { print
+"\$line=<$line> \$line=<" . ($line ? "true" : "false") . "> defined=<
+" . (defined($line) ? "true" : "false") . ">\n"};'
$line=<0> $line=<false> defined=<true>
Or is it? Could it be that both while($somevar = readline(...)) and while($somevar = <...>), but only these, have special semantics? I noticed that if I wrap readline in a function of my own that the special behavior goes away. For example,
use strict;
use warnings;
#The following all output:
# BEFORE
# $line=<0> $line=<false> defined=<true>
# AFTER
#
# while (my $line = readline(*STDIN)) {
# while (my $line = <STDIN>) {
# while (my $line = <>) {
#
# but wrapping readline in a sub produces only
# BEFORE
# AFTER
print "BEFORE\n";
while (my $line = wrapped_readline(\*STDIN)) {
print "\$line=<$line> \$line=<"
. ($line ? "true" : "false") . "> defined=<"
. (defined($line) ? "true" : "false") . ">\n";
}
print "AFTER\n";
sub wrapped_readline {
my $fh = shift @_;
my $sLine = readline($$fh);
#print "wrapped_readline: <$sLine>\n";
return $sLine;
}
Thanks in advance, beth
Update: refined question a bit; fixed error in sub of $_ with $line; added examples using readline and a sub wrapping readline. |