2010-01-28 8 views
7

Come è possibile specificare che Smart :: Comments venga caricato per il mio script originale, nonché per tutti i moduli che carica direttamente. Tuttavia, poiché è un filtro di origine, probabilmente distruggerebbe il caos se applicato a ogni modulo caricato da ogni altro modulo caricato.Come posso usare Smart :: Comments in un modulo che carico senza cambiare la sua origine?

Ad esempio, il mio script include

use Neu::Image; 

vorrei caricare Smart::Comments per Neu::Image pure, ma specificando

 
$ perl -MSmart::Comments script.pl 

non carica Smart::Comments per Neu::Image.

Questo comportamento è descritto nel Smart::Comments documentation:

Se stai debug di un'applicazione che si può anche invocarlo con il modulo dalla riga di comando:

perl -MSmart::Comments $application.pl 

Naturalmente , ciò abilita solo i commenti intelligenti nel file dell'applicazione stesso, non in tutti i moduli caricati dall'applicazione .

A poche altre cose che ho già guardato:

SOLUZIONE Come menzionato da gbacon, Smart :: Comments fornisce un'opzione variabile di ambiente che woul d consentire di accenderlo o spegnerlo. Tuttavia, mi piacerebbe essere in grado di accenderlo senza modificare la fonte originale, se possibile.

+1

"Alcuni uomini non cercano nulla di logico. Non possono essere comprati, vittime di bullismo, ragionate o negoziate con. Alcuni uomini vogliono solo vedere il mondo bruciare. " –

+0

@gbacon: Ti riferisci al mio uso di Smart :: Comments? Sto solo cercando di trovare un modo per giocare con il fuoco "in sicurezza". ;) –

+0

La tua domanda è davvero "Come posso usare Smart :: Commenti in ogni modulo che carico senza cambiare la loro fonte"? –

risposta

10

Quasi certamente si desidera aggiungere use Smart::Comments a moduli che contengono tale e quindi flip the switch in your environment impostando $Smart_Comments in modo appropriato.

Stash-munging, import -quando il patching delle scimmie è una follia.

Ma forse ti piace questo genere di cose. Diciamo che avete Foo.pm:

package Foo; 

use Exporter 'import'; 
our @EXPORT = qw/ foo /; 

#use Smart::Comments; 

sub foo { 
    my @result; 
    for (my $i = 0; $i < 5; $i++) { 
    ### $i 
    push @result => $i if $i % 2 == 0; 
    } 
    wantarray ? @result : \@result; 
} 

1; 

utilizzo ordinaria:

$ perl -MFoo -e 'print foo, "\n"' 
024

ordinaria è noiosa e monotona, naturalmente. Con run-foo, facciamo passi coraggiosi e audaci!

#! /usr/bin/perl 

use warnings; 
use strict; 

BEGIN { 
    unshift @INC => \&inject_smart_comments; 

    my %direct; 
    open my $fh, "<", $0 or die "$0: open: $!"; 
    while (<$fh>) { 
    ++$direct{$1} if /^\s*use\s+([A-Z][:\w]*)/; 
    } 
    close $fh; 

    sub inject_smart_comments { 
    my(undef,$path) = @_; 
    s/[\/\\]/::/g, s/\.pm$// for my $mod = $path; 
    if ($direct{$mod}) { 
     open my $fh, "<", $path or die "$0: open $path: $!"; 
     return sub { 
     return 0 unless defined($_ = <$fh>); 
     s{^(\s*package\s+[A-Z][:\w]*\s*;\s*)$} 
     {$1 use Smart::Comments;\n}; 
     return 1; 
     }; 
    } 
    } 
} 

use Foo; 

print foo, "\n"; 

(Si prega di perdonare la compattezza: l'ho ristretto in modo che si adatterebbe in un blocco senza interruzioni.)

uscita:

$ ./run-foo 

### $i: 0 

### $i: 1 

### $i: 2 

### $i: 3 

### $i: 4 
024

¡ Viva!

Con @INC hooks possiamo sostituire fonti nostre o modificate. Il codice cerca i tentativi di moduli require direttamente utilizzati dal programma. In caso di risposta, inject_smart_comments restituisce un iteratore che produce una riga alla volta. Quando questo furbo, astuto iteratore vede la dichiarazione del pacchetto, aggiunge un pezzo innocente use Smart::Comments al blocco, facendolo apparire come se fosse nella fonte del modulo.

Provando ad analizzare il codice Perl con espressioni regolari, il codice si interromperà se la dichiarazione del pacchetto non si trova su una riga da sola, ad esempio. Condire a piacere.

+0

Grazie. Ho dimenticato l'interruttore dell'ambiente. –

+0

Wow! Voglio dire, WOW! Complimenti a gbacon, il maestro Perl! –

+0

Grazie per i riferimenti agli hook @INC. Non volevo davvero chiedere a te oa nessun altro di fare molto lavoro. Pensavo che potesse esserci qualcosa di più semplice. Wow, questa è una magia fantastica! –

2

Non sembra che questa idea abbia un senso. Se si sta utilizzando Smart::Comments in un modulo, perché non si desidera use Smart::Comments nella sorgente di quel modulo? Anche se si potrebbe ottenere Smart::Comments da applicare a tutti i moduli caricati in uno script via -M, probabilmente non sarebbe una buona idea perché:

  • Stai offuscare il fatto che i moduli utilizzano commenti intelligenti entro non compresa la riga use nella loro origine.
  • Potresti potenzialmente introdurre comportamenti bizzarri dai moduli che hai use nel tuo script, che capita di avere ciò che sembra un commento intelligente, ma in realtà non lo sono. Se un modulo non contiene commenti intelligenti, non dovresti costringerlo giù per la gola.

Come gbacon said, il modo giusto per farlo è quello di use il modulo in ciascuno dei vostri moduli che fanno uso di esso, e poi sopprimere con una variabile d'ambiente quando non si desidera che l'uscita.

Anche come ha detto, è ancora probabilmente possibile farlo con un po 'di follia "Stash-munging, import-dirottaggio scimmia-patch", ma questo è un sacco di lavoro. Non penso che nessuno stia tentando di darti una soluzione in questo senso quando non è una buona idea in primo luogo.

+1

Grazie per la risposta. Per me Smart :: I commenti sono solo per il debug. Dai commenti di Brian cominciai a pensare che ci fosse un altro modo per farlo che non fosse così complicato. Non chiederei a nessuno di fare un sacco di sforzi. –

Problemi correlati