Search code examples
perltestingoperators

Perl: file test operator without condition


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::nameis a directory so -dis a parameter of the function print? Or does Perl explicitly interpret a standalone -d as if -d?


Solution

  • 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