File::Find and $_ in nested subroutines
When running the following code, the filenames of all files below C:\Test are printed. Why doesn't it print just Hello
(n times, depending on how many files are processed)?
Does this imply that I cannot rely on shift
to reliably assign to $_
? Imagine a coworker implements the wtf
function and doesn't know that it's called from a File::Find
wanted sub.
I run this code with Strawberry Perl 5.12
Edit: This code doesn't run as expected either:
use strict;
use warnings;
wanted();
sub wanted{
wtf("Hello");
}
sub wtf {
shift;
print; #expecting Hello
}
So I guess I'm totally off the highway here.. This has obviously nothing to do with File::Find, I'm开发者_StackOverflow中文版 now looking for a new title for this question. Here's my original code:
use strict;
use warnings;
use File::Find;
find(\&wanted, "C:\\test");
sub wanted{
wtf("Hello");
}
sub wtf {
shift;
print; #expecting Hello
}
print
defaults to printing $_
, but shift
defaults to shifting @_
. If you want to get the arguments passed to a subroutine, you should be using @_
, not $_
. shift
returns the shifted value, so you should be doing something like this:
sub wtf {
my $_ = shift;
print;
}
The issue is that your $_
variable is set to the filename but @_
is set to the arguments. The CPAN documentation for File::Find
explains this in detail.
shift
does not assign to $_
.
By the way there are better replacements for File::Find at CPAN - (for example: File::Find::Rules or File::Find::Object). File::Find is really a kind of fossil from the old times petrified by the fact that it got into the core.
精彩评论