2011-03-30 2 views
1

perl에서 if 조건을 테스트하는 가장 좋은 방법은 무엇입니까?전달 된 값을 기반으로 한 Perl 평가 조건

예를 들어, 조건 1이 ($ str1 eq "abc")이고 조건 2가 ($ str2 eq "xyz") 인 경우 런타임에 점검해야 할 조건을 결정할 때, 어떻게 할거 니?

$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

귀하의 예가 과도하게 소진되었을 수 있습니다. 그것은 시도했을 때, 비록 당신이 의도 한대로하지 않았을지라도 (그리고 엄격한/경고와 함께 실패 할 것입니다, 저스틴은 말합니다). $str1$str2의 값은 $cond1$cond2이 할당되면 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

+0

@Chris'eval' 또는 익명의 subs를 사용하면 임의의 조건을 사용할 수 있습니다. 그러나 테스트 조건에 고정 인터페이스를 부여 할 수없는 경우 (즉, 프로그램에서 변수를 볼 필요가있는 경우) 'eval'이 필요합니다. 내장 된 ['sort' 함수] (http://perldoc.perl.org/functions/sort.html)는 사용자가 지정한 조건으로 알고리즘을 조정하는 좋은 예입니다. – Andy

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에 어떤 종류의 것들을 넣었는지 알지 못한다면 그 문제는 평가가 예상 한대로 수행되지 않는다고 생각할 수 있습니다. 문자열로 평가 것에 대해 생각하고 당신은 문제가 나타납니다 :

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

$ 콘드이된다 :에

abc eq "abc" 
당신이 엄격한 경우

및 경고 (당신이해야!) 당신은을 확인 귀하의 평가 결과는 $ @ (해야만합니다!) :

Bareword "abc" not allowed while "strict subs" in use at ..... 
관련 문제