2013-07-30 39 views
-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中,这是怎么做的文件名$bar。所以$bar正在取代\$\&但那是什么?此外,什么可以评估一个字符串给这里什么是这里的正则表达式在这里做

回答

3

它看起来像它取代每个'$ &'与'$ bar'在$foo发生。这是在数据中实现简单占位符令牌语法的典型方法。

eval返回的值是将$foo的值视为Perl源代码的结果。假设正常执行,eval将返回在$foo中评估的最后一个表达式(或者如果执行一个return语句的参数)。请注意,评估$foo也可能有副作用(I/O,变量赋值等)。如果不知道$foo开头是什么,就不可能说更多。

+0

但是$&之前没有$ _,所以它没有引用上述 –

+0

'$&'只是'$ foo'中的文本文本,它正在被替换。 – Barmar

+0

@LukeMakk - 由于正则表达式中的反斜杠,'$&'不被视为Perl特殊变量,而仅仅被视为字符序列。 '$ _'与这里发生的事情无关(除了可能在$ foo中)。 –

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

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的价值?这是真实问题在这里。

Somewhere $dst_dir and $dst_pattern is being set。这是您将FTP中的文件替换为这些字符串的地方。然后我注意到这一点:

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

看来,$dst_dir$dst_file是某种形式的命令?为什么还要用eval在其上运行?这两个字符串的值是什么?为什么通过eval运行?

发生了什么是这两个命令的字符串为$&,并且您正在替换该文件。我们假设$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的原始值,那意味着你第二次经过你的循环,你不会改变$dst_dir$dst_pattern。而且,所有其他时间你也要经历你的循环。

您还没有检查以确保替换实际上有效,并且您没有检查eval是否通过检查[email protected]的值来检查。

最重要的是,你没有设置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 ("[email protected]") { 
     die qq(Evaluation of `$dist_dir` failed!: [email protected]); 
    } 

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

这是检查,以确保置换工作,并且还节约每次不修改您的模板。

+0

请注意,原代码会在替换中转义'$' - 它是/ \ $ \&/ \ $ bar/g'。你代替'$ file'而不是'\ $ file',所以我很怀疑后续使用'eval'是正确的。 –

+0

@TedHopp我会修复我的帖子。谢谢。 –