Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Problem with -d inside find sub

by randian (Acolyte)
on Apr 26, 2012 at 20:14 UTC ( #967450=perlquestion: print w/ replies, xml ) Need Help??
randian has asked for the wisdom of the Perl Monks concerning the following question:

This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux

use strict; use warnings; use 5.010; use File::Find qw/find/; my @all; my @insub; my @outsub; my $dir = 'static'; find sub { my $f = $File::Find::name; push @all, $f; return if -d $f; push @insub, $f; }, $dir; @outsub = grep {!-d} @all; my $all_count = @all; my $insub_count = @insub; my $outsub_count = @outsub; say 'all_count = ', $all_count; say 'insub_count = ', $insub_count; say 'outsub_count = ', $outsub_count;

$dir should be set to a directory that has a little bit of depth to it.

What I expect is that $insub_count should match $outsub_count. What I get is $insub_count matching $all_count;

all_count = 436 insub_count = 436 outsub_count = 408

If you change the sense of the test in the sub to

return if ! -d $f

$insub_count becomes 0!

Similar bizarre behavior occurs with -f.

Comment on Problem with -d inside find sub
Select or Download Code
Re: Problem with -d inside find sub
by moritz (Cardinal) on Apr 26, 2012 at 20:27 UTC

    I think your confusion comes from ignoring this part of the File::Find documentation:

    Additionally, for each directory found, it will "chdir()" into that directory and continue the search, invoking the &wanted function on each file or subdirectory in the directory.

    So the path in $f is always relative (because static is a relative path), and the calls to chdir that File::Find performs take care that the file tests never find the file that you think should be found.

    Either pass the no_chdir => 1 option to &find, or do the file checks on $_ instead of $File::Find::name.

      Duh! Thanks.
        but remember, no_chdir slows things down considerably
      Found another interesting issue. Run the code below as is. It works fine. Then uncomment the given/when blocks and run it again. When I do that I see the same name printed out over and over instead of the correct file names.
      use strict; use warnings; use 5.010; use File::Find qw/find/; my $dir = 'dirname'; my @all; #given ($dir) { #when (-d) { my %options = ( wanted => sub { say; }, no_chdir => 1, ); find \%options, $dir; #} #} local $" = "\n"; say "@all";
        Two solutions:
        1. Declare the %options outside of the given-when blocks.
        2. say $File::Find::name;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://967450]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2015-07-05 06:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls