1

私はPerlの初心者です。ディレクトリ内のすべてのファイルの内容を出力し、ディレクトリ/サブディレクトリ内のすべてのファイルが出力されるまで再帰的に実行する Perl スクリプトを作成しようとしています。私は次のサブルーチンでそれをやっています。

sub print_files_in_dir {
my $file = shift;
if(-d $file){
 my @files=glob "$file/*";
  foreach my $file (@files){
   if(-d $file){
    print_files_in_dir $file;
   }
   else {
    print_file $file;
   }
 } 
 else {
  print_file $file;
 }
}

ここで、print_file は、単一ファイルの内容を出力する sub です。dir2という名前の別のディレクトリを含むdir1というディレクトリでこのコードを実行しようとすると、このエラーが発生します。

パッケージ「dir1/dir2」を介してオブジェクトメソッド「print_files_in_dir」を見つけることができません (おそらく「dir1/dir2」をロードするのを忘れていましたか?)

なぜこのエラーがスローされるのかわかりませんか?

4

4 に答える 4

6

学んだように、引数リストを囲む括弧を省略すると、非常に奇妙なエラーが発生する可能性があります。黙っている人もいます。たとえば、print (4+6)*2印刷10! (OK、必要に応じて警告が表示されている場合は警告が表示されるため、実際には無音ではありませんが、致命的でもありません。)これらの括弧が省略されている場合は注意が必要です。

あなたの問題に気づいたので、これを書いていますglob。パスにスペースなどの特定の文字が含まれていると機能しません。

 glob "$file/*"

する必要があります

 glob "\Q$file\E/*"

そして、私がここにいるので、排除できる冗長性が少しあります。サブは次のように折りたたまれます。

sub print_files_in_dir {
   my $file = shift;
   if (-d $file) {
      print_files_in_dir($_) for glob "\Q$file\E/*";
   } else {
      print_file($file);
   }
}

実際には、File::Find::Ruleを使用してさらに折りたたむことができます。

use File::Find::Rule qw( );
print_file($_) for File::Find::Rule->file->in('.');
于 2012-06-14T00:26:05.970 に答える
4

「間接関数呼び出し」に違反しています。これは、行を引き起こす可能性のある混乱を招く OOP 機能です。

print_files_in_dir $file;

これは、まったく異なる、意図しない何かを意味します。

$file->print_files_in_dir();

関数呼び出しで括弧を使用すると (そのように)、これは起こりません:

print_files_in_dir($file);

についても同様ですprint_file

于 2012-06-13T23:34:46.867 に答える
1

呼び出している時点でprint_files_in_dir、コンパイラはサブルーチンの完全な定義を見ていないため、それが何であるかを認識していません。使用した構文から、最も推測できるのは、それがメソッド呼び出しであるということです。

次のように、定義する前にサブルーチンを事前に宣言することで、この推測を修正できます。

sub print_files_in_dir;

sub print_files_in_dir {

  my $file = shift;

  if (-d $file) {

    my @files = glob "$file/*";

    foreach my $file (@files) {

      if (-d $file) {
        print_files_in_dir $file;
      }
      else {
        print_file $file;
      }
    }
  } 
  else {
    print_file $file;
  }
}
于 2012-06-13T23:54:33.660 に答える
-1

あなたの動機がファイルを再帰的にリストすることである場合は、これを試してください:

     system("ls -R")
于 2012-06-13T23:38:59.780 に答える