开发者

File::Find and $_ in nested subroutines

开发者 https://www.devze.com 2023-01-01 17:16 出处:网络
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)?

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消