File::Find
and the wanted
subroutine
This question is much simpler than the original title ("prototypes and forward declaration of subroutines"!) lets on. I'm hoping the answer, however simple, will help me understand subroutines/functions, prototypes and scoping and the File::Find
module.
With Perl, subroutines can appear pretty much anywhere and you normally don't need to make forward declarations (except if the sub declares a prototype, which I'm not sure how to do in a "standard" way in Perl). For what I usually do with Perl there's little difference between these different ways of running somefunction
:
sub somefunction; # Forward declares the function
&somefunction;
somefunction();
somefunction; # Bare word warning under `strict subs`
I often use find2perl
to generate code which I crib/hack into parts of scripts. This could well be bad style and now my dirty laundry is public, but so be it :-) For File::Find
the wanted
function is a required subroutine - find2perl
creates it and adds sub wanted;
to the resulting script it creates. Sometimes, when I edit the script I'll remove the "sub
" from sub wanted
and it ends up as &wanted;
or wanted();
. But without the sub wanted;
forward declaration form I get this warning:
Use of uninitialized value $_ in lstat at findscript.pl line 29
My question is: why does this happen and is it a real problem? It is "just a warning", but I want to understand it better.
- The documentation and code say
$_
is localized inside ofsub wanted {}
. Why would it be undefined if I usewanted();
instead ofsub wanted;
? - Is
wanted
using prototypes somewhere? Am I missing something obvious inFind/File.pm
? - Is it because
wanted
returns a code reference? (???)
My guess is that the forward declaration form "initializes" wanted
in some way so that the first use doesn't have an empty default variable. I guess this would be how prototypes - even Perl prototypes, such as they exist - would work as well. I tried grepping through the Perl source code to get a sense of what sub
is doing when a function is called using sub function
instead of function()
, but that may be beyond me at this point.
Any help deepening (and speeding up) my understanding of this is much appreciated.
EDIT: Here's a recent example script here on Stack Overflow that I created using find2perl
's output. If you remove the sub
from sub wanted;
you should get the same error.
EDIT: As I noted in a comment below (but I'll flag it here too): for several months I've been using Path::Iterator::Rule
instead of File::Find
. It requires perl >5.10
, but I never have to deploy production code at sites with odd, "never upgrade", 5.8.*
only policies so Path::Iterator::Rule
has become one of those modules I never want to do with out. Also useful is Path::Class
. Cheers.