Perl оценивает условие на основе переданных значений - PullRequest
1 голос
/ 30 марта 2011

Каков наилучший способ проверки условия if в perl, управляемого этим параметром?

Например: если условие 1 - это if ($ 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);
}

Кажется, не работает?

Ответы [ 4 ]

2 голосов
/ 30 марта 2011

Ваш пример может быть перегнан.Это сработало, когда я попробовал, хотя, вероятно, он не делает то, что вы хотели (и он потерпит неудачу со строгими / предупреждениями, как говорит Джастин).Значения $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 голос
/ 30 марта 2011

Почему так много работы?

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 голосов
/ 30 марта 2011

То, как вы пытаетесь достичь этого, довольно странно, может быть проще объяснить, что вы пытаетесь сделать, чтобы найти менее необычный подход.

Во всяком случае, не зная, что вы вкладываете в $ str1 и $ str2, я думаю, что проблема в том, что eval не совсем делает то, что вы ожидаете. Подумайте, к чему относится строка, и вы увидите проблему:

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

$ cond становится:

abc eq "abc"

Что если у вас есть строгие предупреждения и предупреждения (вы должны!) И вы проверяете результат своего eval в $ @ (вы должны!), Вы найдете:

Bareword "abc" not allowed while "strict subs" in use at .....
0 голосов
/ 30 марта 2011

Это не очень полезно с точки зрения того, как бы я спроектировал "что-то , как это". Но это то, как вы могли бы достичь того, что вы показываете

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...