I have this simple code from Perl Cookbook which prints all directories and files recursively:
use File::Find;
@ARGV = qw(.) unless @ARGV;
find sub { print $File::Find::name, -d && '/', "\n" }, @ARGV;
I do not understand the grammar of print $File::Find::name, -d
. How is this to interpret? If -d
tests if $File::Find::name
is a directory so -d
is a parameter of the function print
? Or does Perl explicitly interpret a standalone -d
as if -d
?
No, the -d
is a stand alone statement, it tests $_
. So it is in essence identical to
-d $_ && '/'
Which says "if file is a directory, return a slash character (to print)". The sub
code block is used by the find
function from File::Find
, where $_
contains the file name of the current file.
The commas ,
separate a list of statements that return strings for the print
statement:
print $File::Find::name, # print the files name
-d && '/', # if it is a dir, print /
"\n" # print a newline
In the documentation for -d
(contained in perldoc for -X
where all the file tests are listed) states:
If the argument is omitted, tests $_ ...
This applies to all file tests under -X
.
The reason &&
can be used this way is that it has a higher precedence than the comma operator ,
. This is documented in perldoc perlop