Pregunta

No estoy realmente seguro de cómo llamar a este tipo de expresiones, por lo que un ejemplo sería más fácil ...

¿Hay alguna manera en Perl para evaluar expresiones como a < b <= c? Tengo un archivo de configuración que permite al usuario proporcionar expresiones condicionales para ciertas acciones. En lugar de dividir la condición en dos partes (como lo haría normalmente en el código), me gustaría representarla de esta manera, si es posible.

¿Fue útil?

Solución

Eso viene en Perl 6, seguro. Pero desafortunadamente, no creo que sea una de las cosas de Perl 6 prestado por Perl 5.10.

Otros consejos

Esto es un poco menos legible, pero logra lo que desea: a < b && b <= c

Como otros han mencionado, Perl5 (todavía) no tiene comparaciones encadenadas.

Sin embargo, si está analizando " a < b < = c " desde un archivo de configuración y solo quiero evaluarlo, entonces ¿quizás esto sea lo que buscas?

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" }
    }
}

Es solo un ejemplo rudimentario (es decir, no está completo y no hay verificación de errores), pero creo que se entiende la idea.

Y es posible que ya encuentre algo como esto en CPAN . Algo así como Parse::RPN puede ser un elemento útil.

Ahora, si tu pregunta es sobre cómo analizar literalmente a < b <= c ¡entonces ese es otro caldero de pescado!

/ I3az /

ignorando cualquier validación de entrada o ejecución de la comparación eventual por el momento, el siguiente código (o una variación menor de este) debería poder reescribir su declaración:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top