2013-01-21 35 views
1

我有一種perl「終端」(pastebin code),我們將其稱爲我寫的,其背後的想法是我想逐行運行perl代碼,允許我在現有(大型)數據集上運行新命令,而無需更改腳本並重新加載數據集並重新運行我的腳本。 (請注意,我近一年前寫過這篇文章,現在主要是一個學習實驗(帶有動態功能的平板電腦),但是現在我有一些用處,並且發現了一些妨礙我利用的問題它)。Perl eval命令不能按預期工作

因此,我eval用戶輸入的命令,但是,他們沒有預期的行爲,也許有人可以闡明爲什麼會這樣。

這是'重要'位,我有存儲在@args中的命令行數據,並且第一個元素存儲在$prog中。我檢查是否有現有的函數(我允許用戶創建函數,並且真的濫用引用來獲取動作表),如果沒有,我嘗試並評估命令。

if(exists($actions{$prog})){ 
     print "\n"; 
     $actions{$prog}->(@args); 
     print "\n"; 
}else{ 
     print "\nEVALing '$command'\n"; 
     eval $command; 
     warn [email protected] if [email protected]; 
     print "\n"; 
} 

正如下面可以看到的那樣,它按預期的方式爲標量賦值工作,但是失敗時會分配數組和哈希值。

[email protected]:~/$ perl term.pl 
1358811935>$a = 0; 
EVALing '$a = 0;' 

1358811937>print $a; 
EVALing 'print $a;' 
0 
1358811944>@b = qw(2 3);                          
EVALing '@b = qw(2 3);' 
Global symbol "@b" requires explicit package name at (eval 5) line 1. 

1358811945>print @b; 
EVALing 'print @b;' 
Global symbol "@b" requires explicit package name at (eval 6) line 1. 

1358812008>my @b = qw(2 3);                         
EVALing 'my @b = qw(2 3);' 

1358812008>print "@b"; 
EVALing 'print "@b";' 
Possible unintended interpolation of @b in string at (eval 9) line 1. 
Global symbol "@b" requires explicit package name at (eval 9) line 1. 

1358812016>print join(',',@b);                         
EVALing 'print join(',',@b);' 
Global symbol "@b" requires explicit package name at (eval 10) line 1. 

1358812018> 
+0

如果你只是想以交互方式運行perl,使用調試器:'perl -de 1' – mob

+0

.....好,這將很好地工作。哎呦。哦,我想我會在動態函數表中記下一個很好的學習經驗。 ''___-' – EricR

回答

3

變量$a$b是特殊的,因爲它們是由sort使用。因此,如果沒有聲明,strict不會投訴。使用$x會觸發與數組和散列相同的錯誤。

+0

哇,我什至沒有想到這一點,我一直在修改我的排序'{$ a <=> $ b}'。任何建議,爲什麼我的eval不工作,雖然? – EricR

+0

@EricR:查看更新。 – choroba

+0

好吧,看起來像有'嚴格使用';'是問題所在,並且沒有嚴格的要求。 – EricR

1

對於這種事情,你可能想要允許任意的包變量被用來說no strict 'vars';。在eval'd代碼中聲明一個詞法(my)變量可以工作,但不再處於下一個eval的範圍內。

或者,預先聲明一組變量供eval代碼使用(可能包括%misc散列)。

一種完全不同的方法是每次通過eval將目前輸入的所有代碼串聯起來(如果打印輸出是一個因子,則將輸出重定向到輸入最近的代碼)。