-1
for $file ( $ftp -> ls() )
    {
        $bar = file;                

        $dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
        $dst_pattern =~ s/\$\&/\$bar/g;

        $dst_dir1 = eval( $dst_dir );
        $dst_file = eval( $dst_pattern ); 
    }

Perl では、これは filename に対して何をしているのですか$bar? $bar交換はそうですが、それは\$\&何ですか?また、ここで与えられた文字列で評価されるもの

4

3 に答える 3

3

'$&' の出現箇所をすべて '$bar' に置き換えているよう$fooです。これは、単純なプレースホルダー トークン構文をデータに実装する一般的な方法です。

によって返される値は、 Perl ソース コードであるかのようにevalの値を処理した結果です。$foo通常の実行を想定すると、最後に評価された式 (またはステートメントが実行された場合はステートメントの引数)evalが返されます。評価には副作用 (I/O、変数の代入など) もあることに注意してください。最初に何が入っているかを知らずに、これ以上言うことは不可能です。$fooreturn$foo$foo

于 2013-07-30T15:36:58.183 に答える
0

一つ気になったのは…

for $file ( $ftp -> ls() )
{
    $bar = file;

これはすべきでは$bar = $fileありません$bar = file(あなたのスクリプトは の先頭$にありませんfile)。それ以外の場合は、文字列fileを に入れているだけです$bar

あなたの式の他の部分は次のとおりです。

$dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
$dst_pattern =~ s/\$\&/\$bar/g;

$dst_dirとの値は$dst_pattern? それが本当の質問です。

どこか$dst_dir$dst_pattern設定されています。ここで、FTP のファイルをこれらの文字列に置き換えます。次に、次のことに気付きます。

$dst_dir1 = eval( $dst_dir );
$dst_file = eval( $dst_pattern ); 

$dst_dir$dst_fileはある種のコマンドのように見えますか? 他になぜevalそれらで実行されるのですか?これら 2 つの文字列の値は何ですか? なぜそれらを介して実行するのevalですか?

何が起こっているかというと、これら 2 つのコマンドには文字列$&が含まれており、その文字列を ftp しているファイルに置き換えています。

$dst_dirに等しいとしましょう$ftp->get("$&")。コマンドから取得したファイル名$ftp->ls(それがその文字列に代入されていると仮定しましょうbar.txt。したがって、$dst_dir1に設定され$ftp->get("bar.txt");ます。

ループ全体を見ると、次のようになります。

for $file ( $ftp -> ls() )
{
    $bar = file;                

    $dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
    $dst_pattern =~ s/\$\&/\$bar/g;

    $dst_dir1 = eval( $dst_dir );
    $dst_file = eval( $dst_pattern ); 
}

別の問題が見えます。$&各ファイルをループして$dst_dir、毎回置き換えて$dst_patternいます。ただし、すべてのファイルに対してこれを行っていて、 と の元の値をリセットしていない場合は$dst_dir$dst_pattern. つまり、ループを 2 回目に通過するときは、$dst_dirandは変更されません$dst_pattern。そして、他のすべての場合でも、ループを通過します。

また、置換が実際に機能したかどうかを確認することもeval、 の値をチェックして機能するかどうかを確認することもありません$@

その上、あなたは設定use strict;しておらず、おそらくそうではありませんuse warnings;

ループの新しいバージョンは次のとおりです。

for my $file ( $ftp->ls ) {
    my $dist_dir     = $dst_dir;      # Make sure you don't futz with your
    my $dist_pattern = $dst_pattern;  # original templates!

    # Check to make sure replacements work!
    if ( not $dist_dir =~ s/\$\&/\$file/g ) {
       die qq(Couldn't put file name "$file" into "$dist_dir");
    }
    if ( not $dist_pattern =~ s/\$\&/\$file/g ) {
       die qq(Couldn't put file name "$file" into "$dist_pattern");
    }

    # Check for Eval!
    my $dst_dir1;
    my $dst_file1;
    $dst_dir1 = eval( $dist_dir );
    if ( "$@" ) {
       die qq(Evaluation of `$dist_dir` failed!: $@ );
    }

    $dst_file1 = eval( $dist_pattern );
    if ( "$@" ) {
      die qq(Evaluation of '$dist_pattern' failed!: $@);
    }
}

これは、置換が機能することを確認するためのチェックであり、毎回テンプレートを変更せずに保存することもできます。

于 2013-07-30T17:26:20.253 に答える
0

スニペットが埋め込まれているコードの優れた目的がわからないため、包括的な回答を提供することは困難です。$foo特にとにあるものに関して$bar

evalそれにもかかわらず、特定の置換と次のステートメントを示す小さなスクリプトを書きました。

#!/usr/bin/env perl 

$bar = "10";
$foo = '10*$&';

print 'content of `$bar`: ', $bar, "\n";
print 'content of `$foo` befor substitution: "', $foo, "\"\n";

$foo =~ s/\$\&/\$bar/g;

print 'content of `$foo` after substitution: "', $foo, "\"\n";

$a = eval($foo);

print 'result of the evaluation: ', $a, "\n";

スクリプトの出力は次のとおりです。

content of `$bar`: 10
content of `$foo` befor substitution: "10*$&"
content of `$foo` after substitution: "10*$bar"
result of the evaluation: 100

最後のevalステートメントは、$fooつまりの内容を"10*$bar"、Perl の正規表現であるかのように評価します。したがって、あなたは線を考えることができます

$a = eval($foo);

なので

$a = 10*$bar;

したがって、値100は に格納され$aます。

于 2013-07-30T16:14:03.763 に答える