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
正在取代\$\&
,但这是什么?还会在字符串上评估什么
答案 0 :(得分:3)
看起来它取代了'$&'的每一次出现在$foo
中使用'$ bar'。这是在数据中实现简单占位符令牌语法的典型方法。
eval
返回的值是将$foo
的值视为Perl源代码的结果。假设正常执行,eval
将返回$foo
中评估的最后一个表达式(如果执行了一个return
语句的参数)。请注意,评估$foo
也可能有副作用(I / O,变量赋值等)。如果不知道$foo
中的内容是什么,就不可能多说。
答案 1 :(得分: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
。
答案 2 :(得分: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
?这两个字符串的值是什么?为什么要通过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
的值来检查$@
是否有效。
最重要的是,您没有设置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!: $@);
}
}
这是为了确保替换有效,并且每次都保存不修改模板。