Perl根据传递的值评估条件

时间:2011-03-30 00:39:42

标签: perl parameters eval conditional-statements

在参数驱动的perl中测试if条件的最佳方法是什么?

例如:如果条件1是if($ str1 eq“abc”)而条件2是if($ 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);
}

似乎不起作用?

4 个答案:

答案 0 :(得分:2)

您的例子可能过度提炼。当我尝试它时它起作用了,虽然它可能没有按你的意图行事(并且它会因严格/警告而失败,正如Justin所说)。分配$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);

答案 1 :(得分: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
}

答案 2 :(得分: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;

答案 3 :(得分:0)

你尝试实现这一点的方式很奇怪,可能更容易解释你想要做什么来找到一个不太常见的方法。

无论如何,不​​知道你在$ str1和$ str2中放入了什么样的东西我猜测问题是eval不能完全达到预期效果。考虑字符串的评估结果,您将看到问题:

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

$ cond变为:

abc eq "abc"

如果你有严格的警告(你应该!)并且你在$ @(你应该!)中检查你的评估结果,你会发现:

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