heigold1 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have some code where, i change to a certain directory, read the contents of the directory, and then do a foreach through the contents. I test if each member is a directory using the -d switch, however it seems to be recognizing all files AND direcories as only files. Could someone tell me if i'm using the -d switch properly? Response is greatly appreciated. Here is the code:

sub ScanDirectory{ my ($startdir) = @_; chdir("$stardir\\") or die "Unable to enter dir $startdir:$!\n"; opendir(DIR, "$startdir") or die "Unable to open $workdir:$!\n"; my @names = readdir(DIR) or die "Unable to read $workdir:$!\n"; closedir(DIR); foreach my $name (@names) { next if ($name eq "."); next if ($name eq ".."); if (-d $name) # is this a directory? { print "DIRECTORY $currentDir \n"; } else { print "FILE $currentFile"; # it always passes through this condition. } }
  • Comment on The -d switch isn't working as I expected it to (test to see if its a directory)
  • Download Code

Replies are listed 'Best First'.
Re: The -d switch isn't working as I expected it to (test to see if its a directory)
by Fletch (Bishop) on Jan 07, 2005 at 19:08 UTC
Re: The -d switch isn't working as I expected it to (test to see if its a directory)
by bluto (Curate) on Jan 07, 2005 at 20:29 UTC
    If this is the actual code, then the problem is probably a typo ...

    my ($startdir) = @_; chdir("$stardir\\") or die "Unable to enter dir $startdir:$!\n"; ^^^^^^^
    Since your chdir isn't going where you want, and the names don't have paths prepended to them, the '-d' test will fail. FWIW rather than chdir I usually just prepend the directory name to the paths. This is less error prone since you don't have to remember to chdir back to the previous directory.
      Using chdir is about twice as fast:
      $ perl chdir_benchmar Benchmark: timing 1000 iterations of with_chdir, without_chdir... with_chdir: 16 wallclock secs ( 8.11 usr + 8.46 sys = 16.57 CPU) @ 60.35/s (n=1000) without_chdir: 31 wallclock secs (10.98 usr + 19.15 sys = 30.13 CPU) @ 33.19/s (n=1000)
        Not on my mac G5 with a directory of 10,000 files...

        Benchmark: timing 100 iterations of with_chdir, without_chdir... with_chdir: 25 wallclock secs ( 3.02 usr + 20.31 sys = 23.33 CPU) @ 4 +.29/s (n=100) without_chdir: 28 wallclock secs ( 3.76 usr + 21.65 sys = 25.41 CPU) @ + 3.94/s (n=100)
Re: The -d switch isn't working as I expected it to (test to see if its a directory)
by amw1 (Friar) on Jan 07, 2005 at 19:27 UTC
    This slug will do what you want as well.
    use strict; use File::Find; my $startdir = "/some/directory"; sub wanted { return if ($File::Find::name eq "." || $File::Find::name eq ".."); if(-d $File::Find::name) { print "DIRECTORY " . $File::Find::name , "\n"; } elsif(-f $File::Find::name) { print "FILE " . $File::Find::name . "\n"; } else { print "OTHER " . $File::Find::name . "\n"; } } File::Find::find({wanted => \&wanted}, $startdir);
    there are shorter ways to write this but the basic idea is the same. find2perl is often useful to get a starting point for these as well.