Как я могу вычислить связанные выражения из строки в Perl?
-
22-07-2019 - |
Вопрос
Я не совсем уверен, как называть выражения такого типа, поэтому пример будет проще...
Есть ли в Perl способ оценить такие выражения, как a < b <= c
?У меня есть файл конфигурации, который позволяет пользователю предоставлять условные выражения для определенных действий.Вместо того, чтобы разбивать условие на две части (как я обычно делаю в коде), я хотел бы представить его таким образом, если это возможно.
Решение
Это наверняка в Perl 6. Но, к сожалению, я не думаю, что это одна из вещей из Perl 6, заимствованная из Perl 5.10.
Другие советы
Цепные сравнения представлены в Perl 6.
Теперь будет Можно ли создать подпрограмму последовательного подключения для Perl 5.x ? Это интересный вопрос ...
Это немного менее читабельно, но выполняет то, что вы хотите: a < b && b <= c
Как уже упоминали другие, Perl5 (пока) не имеет цепных сравнений.
Однако, если вы анализируете «a < b <= c» из файла конфигурации и просто хотите его оценить, то, возможно, это то, чем вы руководствуетесь?
use strict;
use warnings;
use 5.010;
my ($a, $b, $c) = (10, 20, 30);
say 'Its true!' if comparison( $a, '<', $b, '<=', $c );
sub comparison {
my $left = shift;
while (my $cmp = shift) {
my $right = shift;
compare( $cmp, $left, $right ) or return;
$left = $right;
}
return 1;
}
sub compare {
my $op = shift;
given ($op) {
when ( '<' ) { return $_[0] < $_[1] }
when ( '<=' ) { return $_[0] <= $_[1] }
default { die "Invalid comparison operator" }
}
}
Это лишь элементарный пример (т.не полный и без проверки ошибок), но я думаю, вы поняли идею.
И возможно, вы уже найдете что-то подобное на CPAN
.Что-то вроде Parse::RPN
возможно, полезный строительный блок.
Теперь, если у вас возник вопрос о том, как буквально анализировать a < b <= c
тогда это еще один котелок с рыбой!
/I3az/
игнорируя любую проверку ввода или выполнение возможного сравнения на данный момент, следующий код (или его незначительное изменение) должен быть в состоянии переписать ваше утверждение:
sub rewrite {
my $str = shift;
my $ops = join "|" => qw/ < > <= >= == != /;
1 while $str =~ s/ ($ops) \s* (\w+?) \s* ($ops) /$1 $2 && $2 $3/xg;
$str
}
print rewrite "a < b < 5 < c != d";
# prints a < b && b < 5 && 5 < c && c != d