2009-06-27 11 views
5

Qual è lo scopo di $1 tramite $9 in Perl? Per esempio, in questo codice:

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

Quale sarà $1 essere? Sarà il primo \w* dal $x o la prima \d* dal secondo \w* in $x?

risposta

17

da perldoc perlre

Le variabili numerate partita ($ 1, $ 2, $ 3, ecc) e il relativo set di punteggiatura ($ +, $ &, $ `, $', e $^N) sono tutti con ambito dinamico fino alla fine del blocco che lo racchiude o fino alla successiva corrispondenza di successo, a seconda dell'evento che si verifica per primo. (Vedere "" istruzioni composte "" in perlsyn.)

Ciò significa che la prima volta che si esegue una regex o la sostituzione in un ambito viene creato un nuovo local copia izzato. Il valore originale viene ripristinato (è locale) quando termina l'ambito. Quindi, $1 sarà 10 fino a eseguire la regex, 20 dopo la regex e 10 di nuovo quando la subroutine è terminata.

Ma io non uso le variabili regex al di fuori di sostituzioni. Trovo molto più chiaro per dire le cose come

#!/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"; 

dove $first e $second hanno nomi che descrivono meglio il loro contenuto.

+0

Non capisco la documentazione che hai citato. Forse non sono chiaro sulle implicazioni di "ambito dinamico". Allora, qual è la risposta alla domanda? –

+0

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

+0

@Rob Kennedy Ho chiarito cosa significa scope dinamico. Potresti anche voler dare un'occhiata a http://perldoc.perl.org/perlfaq7.html#What%27s-the-difference- between-dynamic-and-lexical- (static) -scoping% 3F - Between-local () -and-my()% 3F –

2

Le variabili saranno valide fino alla prossima volta che vengono scritti nel flusso di esecuzione.

Ma in realtà, si dovrebbe usare qualcosa di simile:

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

Quindi utilizzare $ match1 e $ Match2 invece di $ 1 e $ 2, è molto meno ambiguo.

4

Facendo un paio di piccole modifiche al tuo codice di esempio:

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

otteniamo il seguente risultato:

hello 
hello world9 
world9 9 

dimostrando che il $1 è limitata al dynamic scope (cioè il $1 assegnato entro bla cessa di esistere alla fine di tale funzione (ma il $1 assegnato dalla espressione regolare $y è accessibile entro bla fino a quando non viene sovrascritto))

+3

Ancora più importante, penso, mostra che $ 1 * fuori * di bla non è influenzato da cosa succede * dentro * di bla. –