13

File :: Findを使用して、各ファイルを処理する関数にパラメーターを渡すにはどうすればよいですか?

いくつかの3チャンネルTIFFファイルをJPEGファイル(TIFFファイルごとに3つのJPEGファイル)に変換するためにディレクトリをトラバースするPerlスクリプトがあります。これは機能しますが、各ファイルを処理する関数にいくつかのパラメーターを渡したいと思います(グローバル変数を使用する場合を除く)。

これが、パラメーターを渡そうとしたスクリプトの関連部分です。

use File::Find;

sub findFiles
{
    my $IsDryRun2 = ${$_[0]}{anInIsDryRun2};
}

find ( { wanted => \&findFiles, anInIsDryRun2 => $isDryRun }, $startDir);

$isDryRunスカラーです。$startDir文字列であり、ディレクトリへのフルパスです。

$IsDryRun2設定されていません:

TIFFconvert.pl行197(#1)での連結(。)または文字列での初期化されていない値$ IsDryRun2の使用(W未初期化)未定義の値が、すでに定義されているかのように使用されました。「」または0として解釈されましたが、間違いだった可能性があります。この警告を抑制するには、定義された値を変数に割り当てます。

(パラメーターなしの古い呼び出しはfind ( \&findFiles, $startDir);:)


テストプラットフォーム(ただし、本番環境はLinuxマシン、Ubuntu 9.1、Perl 5.10、64ビット):ActiveStatePerl64ビット。WindowsXP。perl -vから:ActiveStateによって提供されるMSWin32-x64-マルチスレッドバイナリビルド1004[287188]用にビルドされたv5.10.0

4

4 に答える 4

16

必要なパラメータを使用して必要なサブを呼び出すサブ参照を作成する必要があります。

find( 
  sub { 
    findFiles({ anInIsDryRun2 => $isDryRun });
  },
  $startDir
);

これは、多かれ少なかれ、カリー化です。かわいらしいカリー化ではありません。:)

于 2010-01-13T12:52:49.937 に答える
3

好きな種類のコード参照を作成できます。名前付きサブルーチンへの参照を使用する必要はありません。これを行う方法の多くの例については、私のFile :: Find::Closuresモジュールを参照してください。この質問に正確に答えるために、そのモジュールを作成しました。

于 2010-02-02T12:01:34.330 に答える
3

PerlMonksのエントリを参照してください。File::Findが嫌いな理由と、クロージャーを使用してそれを行う方法を説明している方法を修正しました。

于 2012-01-08T16:09:12.797 に答える
0
#
# -----------------------------------------------------------------------------
# Read directory recursively and return only the files matching the regex
# for the file extension. Example: Get all the .pl or .pm files:
#     my $arrRefTxtFiles = $objFH->doReadDirGetFilesByExtension ($dir, 'pl|pm')
# -----------------------------------------------------------------------------
sub doReadDirGetFilesByExtension {
     my $self = shift;    # Remove this if you are not calling OO style
     my $dir  = shift;
     my $ext  = shift;

     my @arr_files = ();
     # File::find accepts ONLY single function call, without params, hence:
     find(wrapp_wanted_call(\&filter_file_with_ext, $ext, \@arr_files), $dir);
     return \@arr_files;
}

#
# -----------------------------------------------------------------------------
# Return only the file with the passed extensions
# -----------------------------------------------------------------------------
sub filter_file_with_ext {
    my $ext     = shift;
    my $arr_ref_files = shift;

    my $F = $File::Find::name;

    # Fill into the array behind the array reference any file matching
    # the ext regex.
    push @$arr_ref_files, $F if (-f $F and $F =~ /^.*\.$ext$/);
}

#
# -----------------------------------------------------------------------------
# The wrapper around the wanted function
# -----------------------------------------------------------------------------
sub wrapp_wanted_call {
    my ($function, $param1, $param2) = @_;

    sub {
      $function->($param1, $param2);
    }
}
于 2018-03-04T10:16:06.477 に答える