2009-06-27 23 views
5

¿Cuál es el alcance de $1 a través de $9 en Perl? Por ejemplo, en este código:

sub bla { 
    my $x = shift; 
    $x =~ s/(\d*)/$1 $1/; 
    return $x;  
} 

my $y; 

# some code that manipulates $y 

$y =~ /(\w*)\s+(\w*)/; 

my $z = &bla($2); 
my $w = $1; 

print "$1 $2\n"; 

¿Qué va a ser $1? ¿Será el primero \w* de $x o el primero \d* del segundo \w* en $x?

Respuesta

17

de perldoc perlre

Las variables numeradas fósforo ($ 1, $ 2, $ 3, etc.) y el conjunto de puntuacion relacionados ($ +, $ &, $ `, $' y $^N) son todo tiene un alcance dinámico hasta el final del bloque delimitador o hasta la próxima coincidencia exitosa, lo que ocurra primero. (Véase "Declaraciones" compuestos "" en perlsyn.)

Esto significa que la primera vez que se ejecuta una expresión regular o sustitución en un ámbito se crea una nueva copia local zado. El valor original se restablece (y agrave; la local) cuando finaliza el alcance. Por lo tanto, $1 será 10 hasta que se ejecute la expresión regular, 20 después de la expresión regular y 10 nuevamente cuando la subrutina haya finalizado.

Pero no utilizo las variables regex fuera de las sustituciones. Me parece mucho más claro decir cosas como

#!/usr/bin/perl 

use strict; 
use warnings; 

sub bla { 
    my $x = shift; 
    $x =~ s/(\d*)/$1 $1/; 
    return $x;  
} 

my $y = "10 20"; 

my ($first, $second) = $y =~ /(\w*)\s+(\w*)/; 

my $z = &bla($second); 
my $w = $first; 

print "$first $second\n"; 

donde $first y $second tienen mejores nombres que describen su contenido.

+0

No entiendo la documentación que citó. Tal vez no estoy seguro de las implicaciones de "alcance dinámico". Entonces, ¿cuál es la respuesta a la pregunta? –

+0

Ver http://perl.plover.com/FAQs/Namespaces.html –

+0

@Rob Kennedy He aclarado qué significa el alcance dinámico. También es posible que desee consultar http://perldoc.perl.org/perlfaq7.html#What%27s-the-difference-between-dynamic-and-lexical- (static) -scoping% 3F - Between-local () -and-my()% 3F –

2

Las variables serán válidas hasta la próxima vez que se escriban en el flujo de ejecución.

Pero, en realidad, debería estar usando algo como:

my ($match1, match2) = $var =~ /(\d+)\D(\d+)/; 

A continuación, utilice $ match1 y $ match2 en lugar de $ 1 y $ 2, es mucho menos ambiguo.

4

Al hacer un par de pequeñas modificaciones a su código de ejemplo:

sub bla { 
    my $x = shift; 
    print "$1\n"; 
    $x =~ s/(\d+)/$1 $1/; 
    return $x; 
} 
my $y = "hello world9"; 

# some code that manipulates $y 

$y =~ /(\w*)\s+(\w*)/; 

my $z = &bla($2); 
my $w = $1; 

print "$1 $2\n$z\n"; 

obtenemos el siguiente resultado:

hello 
hello world9 
world9 9 

demostrando que la $1 se limita a la dynamic scope (es decir, el $1 asignado dentro de bla deja de existir al final de esa función (pero el $1 asignado desde el $y regex es accesible dentro de bla hasta que se sobrescriba))

+3

Más importante aún, creo que muestra que $ 1 * fuera * de bla no se ve afectado por pasa * dentro * de bla. –

Cuestiones relacionadas