2013-07-30 37 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我會修復我的帖子。謝謝。 –