2010-08-03 18 views
19

A partire da Perl 5.10, è ora possibile applicare lessicalmente la variabile di contesto $_, esplicitamente come my $_; o in un costrutto given/when.

Qualcuno ha trovato buoni usi del lessicale $_? Rende i costrutti più semplici/più sicuri/più veloci?

E le situazioni che rende più complicate? Il lessicale $_ ha introdotto qualche bug nel tuo codice? (poiché le strutture di controllo che scrivono su $_ utilizzeranno la versione lessicale se è nell'ambito, questo può modificare il comportamento del codice se contiene chiamate di subroutine (a causa della perdita di ambito dinamico))

Alla fine, Mi piacerebbe costruire un elenco che chiarisca quando usare $_ come un lessico, come globale, o quando non ha alcuna importanza.


NB: come di perl5-5.24 queste funzioni sperimentali sono no longer part of perl.

+0

Penso che la risposta alla tua domanda è in gran parte coperto [qui] (http://stackoverflow.com/questions/3393038/does-my-do-anything-if-is-implied) nella risposta alla la mia domanda. – xenoterracide

+0

@xenoterracide => La risposta include certamente alcuni aspetti del lessico '$ _', ma non tutti. Questo è quello che vorrei coprire qui. –

+0

Lo so ma potrebbe anche avere un buon punto di partenza;) – xenoterracide

risposta

8

IMO, una grande cosa da venire fuori lessicale $_ è il nuovo simbolo prototipo _.

Ciò consente di specificare una subroutine in modo che venga eseguita una scalatura o se non ne viene fornita nessuna acquisirà $_.

Così, invece di scrivere:

sub foo { 
    my $arg = @_ ? shift : $_; 

    # Do stuff with $_ 
} 

mi può scrivere:

sub foo(_) { 
    my $arg = shift; 

    # Do stuff with $_ or first arg. 
} 

Non un grande cambiamento, ma è solo che molto più semplice quando voglio che il comportamento. La rimozione della piastra di caldaia è una buona cosa.

Ovviamente, questo ha l'effetto immediato di modificare i prototipi di diversi builtin (ad esempio chr), che potrebbero danneggiare alcuni codici.

Nel complesso, accetto il lessico $_. Mi dà uno strumento che posso usare per limitare i dati accidentali e le interazioni bizzarre tra le funzioni. Se decido di usare $_ nel corpo di una funzione, per lessicalizzarlo, posso essere certo che qualunque sia il codice che chiamo, $_ non verrà modificato nel codice chiamante.

L'ambito dinamico è interessante, ma per la maggior parte desidero lo scoping lessicale. Aggiungi a questo le complicazioni intorno a $_. Ho sentito terribili avvertimenti sull'invisibilità di fare semplicemente local $_; - che è meglio usare invece for ($foo) { }.Lexicalized $_ mi dà quello che voglio 99 volte su 100 quando ho localizzato $_ con qualsiasi mezzo. Lexical $_ offre una grande praticità e una migliore leggibilità.

La maggior parte del mio lavoro ha dovuto funzionare con perl 5.8, quindi non ho avuto la gioia di giocare con lessicale $_ in progetti più grandi. Tuttavia, sembra che questo farà molto per rendere l'uso di $_ più sicuro, che è una buona cosa.

+2

Quali ragioni sono state fornite per 'for ($ pippo) {...}' piuttosto che 'local * _ = \ $ pippo;'? Nella mia esperienza il secondo è un po 'più veloce (dal momento che non è necessario impostare un ambito e un iteratore per la lista di elementi singoli), ma sarei interessato se ci sono problemi di sicurezza da tenere a mente. –

+1

Eric, sono andato a cercare lo specifico riferimento oggi e non sono riuscito a trovarlo. Tutto quello che posso ricordare a questo punto è un avvertimento contro "local $ _" proveniente da "una persona la cui opinione io rispetto" a metà 2009. Quindi, a meno che non sia in grado di comprovare meglio l'affermazione, è meglio ignorarla come nient'altro che per sentito dire. L'affermazione era che la localizzazione non copriva tutti i casi limite con il 'certamente _ $ speciale '. Non ho mai trovato una segnalazione di bug o un caso di test per eseguire il backup dell'avviso. – daotoad

0

Non ho avuto alcun problema qui, anche se tendo a seguire un po 'una politica "Non chiedere, non dire" quando si tratta di magia Perls. Cioè le routine non sono di solito si aspettano di fare affidamento sui loro colleghi che scopano con dati non lessicali come un effetto collaterale, né li lasciano.

Ho provato il codice contro varie versioni 5.8 e 5.10 di perl, mentre uso un 5.6 che descrive Camel per riferimento occasionale. Non ho avuto problemi. La maggior parte delle mie cose sono state originariamente fatte per perl 5.8.8.

3

Una volta ho trovato un issue (errore sarebbe troppo forte di una parola) che si presentava quando stavo giocando con il modulo Inline. Questo semplice script:

use strict qw(vars subs); 
for ('function') { 
    $_->(); 
} 
sub function { 
    require Inline; 
    Inline->bind(C => <<'__CODE__'); 
void foo() 
{ 
} 
__CODE__ 
} 

fallisce con un messaggio di errore di Modification of a read-only value attempted at /usr/lib/perl5/site_perl/5.10/Inline/C.pm line 380.. In profondità all'interno del modulo Inline è una subroutine che voleva modificare $_, portando al messaggio di errore sopra.

Utilizzando

for my $_ ('function') { ... 

o comunque dichiarare my $_ è una soluzione valida a questo problema.

(Il modulo Inline è stato riparato per risolvere questo particolare problema).

1

[Motivazione: Una breve risposta aggiuntiva con un breve riepilogo per perl nuovi arrivati ​​che potrebbero passare. Quando si cerca "argomento lessicale perl" si può finire qui.]

Ormai (2015) suppongo sia noto che l'introduzione di argomento lessicale (my $_ e alcune funzioni correlate) ha portato ad alcune difficoltà da rilevare a i comportamenti non intenzionali all'inizio e così era marked come experimental e quindi inserito in un deprecation stage.


sintesi parziale di#RT119315: Un suggerimento era per qualcosa come use feature 'lextopic';to make use of a new lexical topic variable: $^_. Un altro punto è stato che un "implicit name for the topicalizing operator ... other than $_" avrebbe funzionato meglio se combinato con funzioni esplicitamente lessicali (, ad esempio lessicale map o lmap). Se questi approcci avrebbero in qualche modo permesso di salvare given/when non è chiaro. Nell'aldilà delle fasi sperimentali e di deprezzamento forse qualcosa potrebbe finire per vivere nel fiume di CPAN.