zedoo
zedoo

Reputation: 11277

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 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 
}

Upvotes: 3

Views: 332

Answers (3)

zby
zby

Reputation: 2465

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.

Upvotes: 0

jasonmp85
jasonmp85

Reputation: 6817

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.

Upvotes: 4

daxim
daxim

Reputation: 39158

shift does not assign to $_.

Upvotes: 2

Related Questions