Why is the return variable value of a subroutine not assigned to the $ _ variable by default
I have a Perl routine that updates an RSS feed. I want to check the return value, but the function is used in many places, so I wanted to just check the default variable $_
, which I understand should be assigned to the return value if no variable is specified.
The code is too long to include it all, but essentially it does the following
sub updateFeed {
#....
if($error) {
return 0;
}
return 1;
}
Why then
$rtn = updateFeed("My message");
if ($rtn < 1) { &Log("updateFeed Failed with error $rtn"); }
DO NOT log error
then
updateFeed("myMessage");
if ($_ < 1) { &Log("updateFeed Failed with error $_"); }
logs an error " updateFeed Failed with error
"? (Note that there is no value at the end of the message.)
Can anyone tell me why the default variable is empty string or undef?
source to share
A normal function call is not one of the $_
implicitly used contexts .
Here's what perldoc perlvar
(as of version 5.1.14) has to say about $_
:
$ _
By default, enter and search by pattern. The following pairs are equivalent:
while (<>) {...} # equivalent only in while!
while (defined($_ = <>)) {...}
/^Subject:/
$_ =~ /^Subject:/
tr/a-z/A-Z/
$_ =~ tr/a-z/A-Z/
chomp
chomp($_)
Here are the places where Perl will accept $ _ even if you're not using it:
The following functions use $ _ as their default argument:
abs, alarm, chomp, chop, chr, chroot, cos, defined, eval, exp, glob, hex, int, lc, lcfirst, length, log, lstat, mkdir, oct, ord, pos, print, quotemeta, readlink, readpipe, ref, require, inverse (only in scalar context), rmdir, sin, split (on second argument), sqrt, stat, study, uc, ucfirst, unlink, unpack.
All tests are files (
-f
,-d
) except-t
, which is STDIN by default. See-X
at perlfuncPattern matching operations
m//
,s///
andtr///
(akay///
) when used without an operator=~
.The default iterator variable in a loop
foreach
unless another variable is specified.Implicit iterator variable in functions
grep()
andmap()
.Implicit variable
given()
.The default place to enter an input record is when the result of an operation is
<FH>
verified by itself as the only test criterionwhile
. Outside the test,while
this will not happen.Since $ _ is a global variable, this can lead to unwanted side effects in some cases. As of perl 5.9.1, you can now use the lexical version of $ _ by declaring it in a file or in a block with
my
. Moreover, the declarationour $_
restores the global $ _ in the current scope.Mnemonic: Underline is understood in certain operations.
source to share
$_
by default not set by routines in void context. You can write your own subsets to set $_
when it's empty context. You will start by checking the value wantarray
and set $_
when wantarray
undefined.
sub updateFeed {
...
my $return
...
if($error) {
$return = 0;
}else{
$return = 1;
}
# $return = !$error || 0;
if( defined wantarray ){ # scalar or list context
return $return;
}else{ # void context
$_ = $return;
}
}
I would recommend not doing this as it might come as a surprise to someone using your routine. Which can make it difficult to debug their program.
The only time I will do this is when emulating an inline routine .
source to share