views:

55

answers:

3

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 
}
+2  A: 

shift does not assign to $_.

daxim
See my comment on jasonmp85's answer.
zedoo
+4  A: 

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.

jasonmp85
Gosh I really confused things here..
zedoo
No biggie. Perl is just confusing.
jasonmp85
A: 

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.

zby