Я ищу способ сделать это в Perl:
$a = "60"; $b = "< 80";
if ( $a $b ) { then .... }
Здесь, $b
"содержит" оператор... я могу сделать это? Возможно, некоторый другой путь?
$a = "60"; $b = "< 80";
if( eval($a. $b)){
print "ok";
}
подробнее см. perldoc eval
Приятно видеть, как люди открывают для себя функциональное программирование. : -)
К счастью, Perl имеет возможность создавать и сохранять функции на лету. Например, образец в вашем вопросе будет выглядеть так:
$a = "60"; $b = sub { $_[0] < 80 };
if ( $b->($a) ) { .... }
В этом примере ссылка на анонимную подпрограмму хранится в $ b
, подпрограмма имеет тот же синтаксис для передачи аргументов, что и обычно. один. ->
затем используется для вызова по ссылке (тот же синтаксис, который вы, вероятно, используете для ссылок на массивы и хэши).
Но, конечно, если вы хотите просто построить выражения Perl из произвольных строк, вы можете использовать eval
:
$a = "60"; $b = " < 80";
if ( eval ("$a $b") ) { .... }
Однако делать это через eval
нельзя. безопасно, если строка, которую вы оцениваете, содержит части, которые вводятся пользователем. Синан Унур прекрасно объяснил это в своем комментарии-ответе .
Как насчет определения функции, которая обертывает необходимое условие:
my $cond = sub { $_[0] < 80 };
if ( $cond->( $a ) ) {
...
}
Это должен быть комментарий, но комментарии слишком тесны для чего-то вроде этого, поэтому я делаю его CW.
Для случая, который вы показали, где содержимое переменных, которые собираются передать в string eval , принятое решение является правильным.
Если, однако, содержимое $ a
и $ b
поступает из пользовательского ввода, то обратите внимание на следующий сценарий:
#!/usr/bin/perl
use strict; use warnings;
my $x = '80';
my $y = '; warn "evil laugh!\n"; exit';
if ( eval ($x . $y) ) {
print "it worked!!!\n";
}
Если строки вводятся с помощью пользователю, ничто не мешает ему передать вашей программе строку '; system "rm -rf / bin"'
.
Итак, для правильного решения вашего вопроса потребуется написать или использовать синтаксический анализатор выражений.
Кстати, вы не должны использовать $ a
и $ b
в качестве имен переменных, поскольку это волшебные локальные переменные пакета, используемые sort , и поэтому они освобождены от strict - и вы должны всегда использовать strict и предупреждения в своих программах.
Интересно, представляет ли здесь интерес Number::Compare? Из примера:
Number::Compare->new(">1Ki")->test(1025); # is 1025 > 1024
my $c = Number::Compare->new(">1M");
$c->(1_200_000); # slightly terser invocation