2011-03-30 63 views
1

在perl中測試參數驅動的if條件的最佳方法是什麼?例如:如果條件1是if($ str1 eq「abc」)並且條件2是if($ str2 eq「xyz」),並且在運行時做出關於哪個條件需要被檢查的決定,你會怎麼做?Perl根據傳遞的值對條件進行評估

$str1 = $ARGV[0]; 
$str2 = $ARGV[1]; 
$cond_value = $ARGV[2]; 

$cond1 = "$str1 eq \"abc\""; 

$cond2 = "$str2 eq \"xyz\""; 

if($cond_value == 1) { 
    $return_val = eval($cond1); 
} 
else { 
    $return_val = eval($cond2); 
} 

似乎不工作?

回答

2

您的示例可能過度提煉。當我嘗試時,它很有效,但它可能沒有達到你想要的目標(如Justin所說,它會因嚴格/警告而失敗)。當$cond1$cond2被分配時,$str1$str2的值被擴展,而不在if ($cond_value)內。這可以通過轉義美元符號來解決($cond1 = "\$str1 eq \"abc\"";)。

eval存在一系列問題,包括如果您使用不受信任的數據來處理正確的轉義以及可能存在的安全風險的問題。你可能想要考慮使用匿名子程序:

$cond1 = sub { $_[0] eq "abc" }; 
$cond2 = sub { $_[1] eq "xyz" }; 

$test = $cond_value ? $cond1 : $cond2; 

$return_val = $test->($str1, $str2); 
+0

但我面臨的問題是,它可能並不總是一個「eq」的比較。它可以是<=或任何這樣的操作符。需要將整個條件作爲變量傳遞。 – Chris 2011-03-30 02:59:51

+0

@Chris無論是「eval」還是匿名子,您都可以使用任意條件。然而,如果測試條件不能給定一個固定的接口(即,如果條件可能需要查看程序中的任何變量),那麼'eval'就是要走的路。內置的['sort'函數](http://perldoc.perl.org/functions/sort.html)是一個調整用戶指定條件算法的好例子。 – Andy 2011-03-30 03:33:20

1

爲什麼這麼多工作?

my $str_to_test = $cond_value == 1 ? $str1 : $str2; 
my $test_against = $cond_value == 1 ? "abc" : "xyz"; 

if($str_to_test eq $test_against) { 
    # do stuff 
} 
0

這是不是從我將如何工程師「像這樣東西」透視這很有幫助。但這就是你如何能夠完成你所展示的東西

my $cond = $ARGV[2]; 
my $return_val = $ARGV[$cond - 1] eq [ qw<abc xyz> ]->[$cond - 1]; 

我只是不能從這個玩具程序中看到更廣泛的應用。這裏的另一個變化:

my $return_val = $ARGV[$_] eq [ qw<abc xyz> ]->[$_] for $ARGV[2] != 1 || 0; 
0

你想做到這一點是很奇怪的方式,它可能是更容易解釋你正在嘗試做的,找到一個不太尋常的做法。

無論如何,不​​知道你在$ str1和$ str2中放置了什麼樣的東西,我猜測問題在於eval沒有達到你所期望的。想想字符串的計算結果爲,你會看到這個問題:

$str = "abc"; 
$cond = "$str eq \"abc\""; 

$ COND變爲:

abc eq "abc" 

如果您有嚴格和警告(您應該!),你檢查您在$ @中的評估結果(您應該!)您會發現:

Bareword "abc" not allowed while "strict subs" in use at .....