2009-11-04 4 views
14

So cosa fanno tutti, ma non mi sono mai trovato in una situazione in cui avevo bisogno di qualcuno di loro. Ho usato i blocchi BEGIN in molte occasioni e END s una volta ogni tanto. BEGIN è particolarmente utile quando è necessario modificare l'ambiente prima dell'esecuzione del codice e ho utilizzato END in determinate situazioni di debug per intercettare informazioni importanti sullo stato per errori fatali difficili da rintracciare.Qual è l'utilità dei blocchi CHECK, UNITCHECK e INIT in Perl?

Hai mai usato CHECK, UNITCHECK o INIT? Se sì, per cosa? E un blocco BEGIN non sarebbe stato sufficiente per qualche motivo?

La documentazione per i blocchi è PerlDoc.

risposta

5

Avevo una funzione di pacchetto import che eseguiva alcune operazioni pesanti e quindi effettuava una chiamata eval. Come fai il debug di qualcosa del genere? La funzione di importazione viene eseguita quando il modulo è use, che si svolge in fase di compilazione (come se si trovasse all'interno di un blocco BEGIN). Per qualche ragione (penso fosse perché avevo bisogno di passare i parametri a import con notazione heredoc, ma avrebbe potuto essere qualcos'altro), non era abbastanza buono da dire require Module; Module->import(@args).

Quindi la mia soluzione era creare la stringa per eval in import e salvarla un'altra variabile. Quindi ho eseguito il eval in un blocco INIT. Quando si eseguiva il debugger, il primo punto di esecuzione era all'inizio del blocco INIT e potevo usare il debugger per scorrere l'istruzione eval.

+0

Ora mi ricordo perché non volevo eseguire 'require Module; Module-> import (@stuff)'. Era perché avevo già una serie di script di test che volevo poter eseguire il debug e non volevo modificare l'istruzione 'use Module' in ogni file. – mob

+9

Non è necessario passare attraverso tali contorsioni per eseguire il debug del codice di compilazione. Basta posizionare $ DB :: single = 1 in qualsiasi punto dell'origine e il debugger si fermerà a quel punto, indipendentemente dalla fase di elaborazione del programma. (Vedere http://perldoc.perl.org/perldebug.html#Debugging -compile-time-statement) –

+0

Grazie Brian! Buono a sapersi. – mob

7

Un uso interessante dei blocchi CHECK è in "Advanced Perl programming" di Simon Cozens (O'Reilly) nel capitolo 1, nella sezione "Fare cose dopo con CHECK". Mostra come implementare l'attributo "finale" java-like

Inoltre, Devel :: Sub :: Trace utilizza i blocchi INIT per incidere tracce (questa informazione proviene da POD per Devel :: Hook, che è un modulo utilizzato per lavorare con quei blocchi denominati)

+0

Inoltre, non l'ho mai provato ma questi * potrebbero * essere plausibilmente sfruttati per alcuni approcci di derisione interessanti - se qualcuno ha un'idea, sentitevi liberi di ampliare questa possibilità come una risposta separata. – DVK

3

Well BEGIN I blocchi vengono eseguiti in fase di compilazione, come sai. Quindi tengo il codice che deve essere eseguito affinché il mio modulo possa essere importato.

Ho scritto un wrapper di script per fare tutto ciò che veniva fatto nel codice di codice che si verificava in un paio di script.

  • C'erano cose che dovevo fare per ottenere la lettura del modulo da use -d. Che ho eseguito nei blocchi BEGIN e import sub.
  • Ma c'era anche tutto il boilerplate che inizializzava i servizi che lo script avrebbe usato. Pertanto, ho eseguito queste azioni nei blocchi INIT.
  • E ha eseguito la necessaria pulizia e il codice di uscita nei blocchi END.

Penso che CHECK abbia senso se si scrivono moduli con motori XS, ma l'ho usato solo una manciata di volte. Una volta penso che fosse per controllare i suggerimenti in Perl intermedio. E non riesco a ricordare a memoria le altre ragioni.

Ma io uso i blocchi INIT quando ritengo che il codice sia più parte dello script, piuttosto che configurare il modulo. In sostanza, faccio solo ciò che è necessario durante la compilazione.

+0

Axeman - per l'inizializzazione, potresti chiarire quali erano i tuoi usi in cui il blocco INIT stava fornendo qualcosa di speciale non ottenibile semplicemente inserendo il codice di init all'inizio del programma regolare? È solo per la visualizzazione/facilità di manutenzione? – DVK

+1

@DVK: ho usato i blocchi INIT nei moduli per eseguire l'inizializzazione della classe; l'utente non dovrebbe sapere di quel genere di cose. Sfortunatamente, PAR :: Packer ha problemi con i blocchi programmati (INIT e CHECK in particolare), quindi questo non funziona per i moduli che potrebbero essere distribuiti in quel modo. Di solito finisco per estrarre il blocco INIT in favore di un sotto 'initialize()' che viene chiamato la prima volta che viene richiamato il costruttore. –

+0

I blocchi CHECK non hanno nulla a che fare con i moduli XS. – rurban

1

perlmod spiega quei blocchi speciali ma in realtà solo BEGIN e END sono comunemente usati. Sono solo array di CV, LIFO o FIFO. Questi blocchi consentono temporizzazioni separate quando il codice viene eseguito, indipendentemente dalla posizione nel file di origine. Quindi è possibile mantenere insieme le sezioni di codice, ma vengono eseguite in momenti diversi (PHASES).

VERIFICA stato aggiunto inizialmente per eseguire la suite compilatore O (-MO=C...) in un ordine fisso dopo il modulo di inizializzazione (pacchetto utilizzo), e prima che il programma principale, per essere in grado negozio contesto di esecuzione lì. Questo separa il tempo di compilazione (prima) dal tempo di esecuzione (dopo). perl -c si ferma dopo CHECK.

Dato che sono il manutentore dei compilatori, utilizzo CHECK e -MO = estensivamente. I miei moduli compile() sono chiamati da O all'interno di un blocco CHECK. Con o (debug O) Io chiamo il metodo compile non in CHECK, ma più tardi in INIT, quindi il debugger vi entra. Il debugger non passa ai blocchi CHECK per impostazione predefinita, è necessario forzarlo con $DB::single=1 o utilizzare Od.

UNITCHECK è stato aggiunto in seguito alla compilazione del modulo a grana fine e al caricamento, esp. .pmc file.

Non l'ho mai usato fino ad ora. Può anche accadere in fase di esecuzione, quindi potrei usarlo per i controlli di tipo dei moduli caricati in fase di esecuzione.

INIT è stato quindi aggiunto per consentire l'inizializzazione della classe separata.

Raramente lo uso, ma è utile.

+0

A quanto pare, ti sei perso: "Hai mai usato CHECK, UNITCHECK o INIT? Se sì, per cosa? E un blocco BEGIN non sarebbe stato sufficiente per qualche motivo?" Questo tipo di spiegazione sottile, l'OP può arrivare ovunque. – Axeman