2009-05-10 13 views
27

¿Existe una manera ordenada de hacer una sentencia de caja o conmutador en Perl 5 ?. Me parece que deberían incluir un interruptor en la versión 6 ..Obtenga un comportamiento de conmutador/caja en Perl 5

Necesito esta estructura de control en una secuencia de comandos, y he oído que puede importar un "módulo de conmutación". Pero, ¿cómo puedo lograrlo sin importar para minimizar las dependencias y adquirir la portabilidad?

+4

El módulo Switch es parte de Core Perl, y lo ha sido desde 5.8, por lo que no hay ningún problema de dependencia; sin embargo, tiene algunos errores y limitaciones. Consulte los documentos para obtener más información, o mejor aún, actualice a 5.10 y obtenga una declaración de cambio, operador de coincidencia inteligente, por ejemplo, función, variables de estado, un host de mejoras de expresiones regulares, definido o (//), operadores de prueba de archivos apilados (- r -x $ archivo en lugar de -r $ archivo && -x _), y una serie de otras mejoras. –

+0

@lurks, es posible que desee seleccionar una respuesta diferente. –

Respuesta

57

Si está utilizando Perl 5.10 usted tiene given/when que es una instrucción switch (nota, se puede hacer algo más que comparar con expresiones regulares, leer los documentos vinculados a ver todo su potencial):

#or any of the dozen other ways to tell 5.10 to use its new features 
use feature qw/switch/; 

given($string) { 
    when (/^abc/) { $abc  = 1; } 
    when (/^def/) { $def  = 1; } 
    when (/^xyz/) { $xyz  = 1; } 
    default  { $nothing = 1; } 
} 

Si están usando Perl 5.8 o anterior debe conformarse con if/elsif/else declaraciones:

if ($string =~ /^abc/) { $abc  = 1; } 
elsif ($string =~ /^def/) { $def  = 1; } 
elsif ($string =~ /^zyz/) { $xyz  = 1; } 
else      { $nothing = 1; } 

o anidado condition operators (?:):

$string =~ /^abc/ ? $abc  = 1 : 
$string =~ /^def/ ? $def  = 1 : 
$string =~ /^xyz/ ? $xyz  = 1 : 
        $nothing = 1; 

Hay un módulo en el núcleo de Perl (Switch) que le da instrucciones switch falsos a través de source filters, pero es mi entendimiento de que es fragile:

use Switch; 

switch ($string) { 
    case /^abc/ { 
    case /^abc/ { $abc  = 1 } 
    case /^def/ { $def  = 1 } 
    case /^xyz/ { $xyz  = 1 } 
    else  { $nothing = 1 } 
} 

o la sintaxis alternativa

use Switch 'Perl6'; 

given ($string) { 
    when /^abc/ { $abc  = 1; } 
    when /^def/ { $def  = 1; } 
    when /^xyz/ { $xyz  = 1; } 
    default  { $nothing = 1; } 
} 
+0

La versión Perl 5.10 establece $ _ como lo hace en Perl 6. el módulo Switch está dado/cuando no lo hace. –

+2

'when' es un operador implícito '~~', por lo que no solo se permiten las expresiones regulares. –

16

La sugerencia en Programming Perl es:


for ($string) { 
    /abc/ and do {$abc = 1; last;}; 
    /def/ and do {$def = 1; last;}; 
    /xyz/ and do {$xyz = 1; last;}; 
    $nothing = 1; 
} 
7

Una solución equivalente que me gusta es dispatch table.

my $switch = { 
    'case1' => sub { print "case1"; }, 
    'case2' => sub { print "case2"; }, 
    'default' => sub { print "unrecognized"; } 
}; 
$switch->{$case} ? $switch->{$case}->() : $switch->{'default'}->(); 
+4

Más corto: '($ switch -> {$ case} || $ switch -> {default}) ->()' – ephemient

+0

¡Esto es hermoso! – neevek

9

Sólo un breve comentario sobre el módulo principal Switch que se ha mencionado un par de veces en las respuestas. El módulo en cuestión se basa en filtros de origen. Entre otras cosas, eso puede dar como resultado líneas incorrectas informadas por errores. Es tan malo que ninguno de los desarrolladores principales realmente recuerda o se preocupa por recordar por qué fue aceptado en el núcleo perl en primer lugar.

Además, Switch.pm será el primer módulo de Perl que se haya eliminado del núcleo perl. La próxima versión principal de perl, 5.12.0, seguirá teniendo, aunque con una advertencia de desaprobación. Esa advertencia de desactivación desaparecerá si usted instala explícitamente Switch.pm desde CPAN. (Obtienes lo que pides). En el siguiente lanzamiento, 5.14, Switch.pm se eliminará por completo del núcleo.

0
print("OK : 1 - CANCEL : 2\n"); 
my $value = <STDIN>; 
SWITCH: { 
    ($value == 1) && last(SWITCH); 
    ($value == 2) && do {print("Cancelled\n"); exit()}; 
    print("??\n"); 
} 
+1

Considere agregar una descripción de su respuesta. – DontVoteMeDown

Cuestiones relacionadas