2

以下の例は両方ともOKですか、それとも2番目の例は悪いスタイルですか?

ケース1:トップディレクトリにとどまり、catdirを使用してサブディレクトリにアクセスする

#!/usr/bin/env perl
use warnings; use strict;

my $dir = 'my_dir_with_subdir';
my ( $count, $dh );

use File::Spec::Functions;
$count = 0;

opendir $dh, $dir or die $!;
while ( defined( my $file = readdir $dh ) ) {
    next if $file =~ /^\.{1,2}$/;
    my $sub_dir = catdir $dir, $file;
    if ( -d $sub_dir ) {
        opendir my $dh, $sub_dir or die $!;
        while ( defined( my $file = readdir $dh ) ) {
            next if $file =~ /^\.{1,2}$/;
            $count++;
        }
        closedir $dh or die $!;
    }
    else {
        $count++;
    }
}

closedir $dh or die $!;
print "$count\n";

ケース2:サブディレクトリに変更し、終了する前にトップディレクトリを復元する

use Cwd;
my $old = cwd;
$count = 0;
opendir $dh, $dir or die $!;
chdir $dir or die $!;
while ( defined( my $file = readdir $dh ) ) {
    next if $file =~ /^\.{1,2}$/;
    if ( -d $file ) {
        opendir my $dh, $file or die $!;
        chdir $file or die $!;
        while ( defined( my $file = readdir $dh ) ) {
            next if $file =~ /^\.{1,2}$/;
            $count++;
        }
        closedir $dh or die $!;
        chdir $dir;
    }
    else {
        $count++;
    }
}
closedir $dh or die $!;
chdir $old or die $!;
print "$count\n";
4

3 に答える 3

2

あなたの質問は、あなたが通過しているディレクトリに変更するべきか、それともトップレベルのディレクトリに留まるべきかということです。

答えは:それは異なります。

たとえば、File::Findについて考えてみます。デフォルトの動作は、実際にディレクトリを変更することです。ただし、モジュールには、no_chdir望ましくない場合のオプションも用意されています。

あなたの例の場合、File::Findすべてのサブディレクトリを繰り返したくないので、おそらく適切ではありませんが、1つだけです。これは、スクリプトのFile :: Slurp::read_dirベースのバリエーションです。

#!/usr/bin/perl

use strict; use warnings;

use File::Slurp;
use File::Spec::Functions qw( catfile );

my ($dir) = @ARGV;

my $contents = read_dir $dir;
my $count = 0;

for my $entry ( @$contents ) {
    my $path = catfile $dir, $entry;
    -f $path and ++ $count and next;
    -d _ and $count += () = read_dir $path;
}

print "$count\n";
于 2010-02-11T11:22:25.503 に答える
1

たとえば、サブディレクトリに変更するのが最善であり、最後に元のディレクトリに変更する必要はありません。これは、各プロセスに独自の「現在のディレクトリ」があるためです。したがって、perlスクリプトが独自の現在のディレクトリを変更しているからといって、シェルの現在のディレクトリが変更されているわけではありません。それは変更されません。

これがより大きなスクリプトの一部である場合、それは異なります。私の一般的な好みは、ディレクトリを変更しないことです。スクリプトの任意の時点で現在のディレクトリが何であるかについての混乱を減らすためです。

于 2010-02-11T12:14:19.073 に答える
0

すでに提案したように、File::Findを使用してください:)

ウォーキングダイアについて本当に学びたいのでない限り、ほとんどの場合、このような問題を解決するためにモジュールを使用する方が、自分でロールするよりも優れています...

于 2010-02-11T08:45:15.923 に答える