2011-12-07 8 views
8

L'esempio che segue è riportata nella Paul Graham ANSI Common Lisp come esempio di fare incapsulamento:è meglio mettere il defpackage in un file separato durante la creazione di pacchetti

(defpackage "CTR" 
    (:use "COMMON-LISP") 
    (:export "COUNTER" "INCREMENT" "CLEAR")) 

(in-package ctr) 

;function definitions here 

Tuttavia, in Peter Seibels Practical Common Lisp, Link here, dice:

Poiché i pacchetti sono usati dal lettore, un pacchetto deve essere definito prima di poter caricare o in fase di compilazione FILE un file che contiene un in-package espressione di passare a quel pacchetto. I pacchetti devono essere definiti anche prima che altri moduli DEFPACKAGE possano riferirsi a loro ... Il primo passo per assicurarsi che i pacchetti esistano quando hanno bisogno di consiste nel mettere tutti i tuoi DEFPACKAGE in file separati dal codice che deve essere letto in quei pacchetti

Quindi lui consiglia di creare due file per ogni pacchetto, uno per il pacchetto e uno per il codice. I file contenenti defpackages dovrebbero iniziare con (in-package "COMMON-LISP-USER").

Per me sembra che mettere il defpackage nello stesso file, prima del pacchetto e del codice, sia un buon modo per garantire che il pacchetto sia definito prima dell'uso. Quindi il primo metodo, raccogliere tutto in un unico file sembra più facile. Ci sono problemi con l'utilizzo di questo metodo per la creazione del pacchetto?

risposta

8

penso che l'utilizzo di un file separato per defpackage è una buona abitudine perché:

  • Non «inquinare» i file con defpackage.
  • Rende più facile trovare i simboli esportati/in ombra/..., è sapere che devi solo guardare package.lisp.
  • Non devi preoccuparti per l'ordine quando usi ASDF.

    (defsystem :your-system 
        :components ((:file "package") 
           ... the rest ...))` 
    
  • Peter Seibel dice così;)

EDIT: Ho dimenticato di dire quickproject che facilita la creazione di nuovi progetti CL.

REPL> (quickproject:make-project "~/src/lisp/my-wonderful-project/" 
           :depends-on '(drakma cl-ppcre local-time))` 

Questo comando creerà una directory "~/src/lisp/my-wonderful-project/" e i seguenti file:

  • package.lisp
  • my-wonderful-project.asd (filled)
  • my-wonderful-project.lisp
  • README.txt

E quindi, penso che sia bene usare la stessa convenzione.

+2

Penso che l'ordine sia la ragione più importante di questi, e ce n'è un'altra: i pacchetti divisi su più file. –

+1

Sono d'accordo con te, tranne nel caso di progetti a file singolo, in cui puoi inserire la definizione del pacchetto nello stesso file. AFAIK, non è proibito dallo standard. –

+0

Più file e ordini quando si usa ASDF ha senso. I primi due punti sembrano più una preferenza individuale. – snowape

1

Tendo a utilizzare più file di codice sorgente, un singolo file "packages.lisp" e un singolo file di definizione di sistema "project.asd" per la maggior parte dei miei progetti. Se il progetto richiede più pacchetti, sono tutti definiti in "packages.lisp", con le esportazioni pertinenti sul posto esportate.

0

C'è questo motivo per inserire DEFPACKAGE nel proprio file: se si dispone di un pacchetto di grandi dimensioni, si potrebbero avere diversi gruppi di funzioni correlate e si potrebbe desiderare di avere file di origine separati per gruppo di funzioni. Quindi tutti i file sorgente avrebbero il proprio IN-PACKAGE in cima, ma tutti "condividono" il DEFPACKAGE esterno. Quindi, finché si carica DEFPACKAGE per primo, non importa l'ordine di caricamento degli altri file di origine.

Un esempio al momento in cui sto lavorando ha più classi nel pacchetto e i file di origine sono suddivisi in base alla classe, ognuno con una definizione di classe e la relativa funzione generica e le definizioni dei metodi.

Problemi correlati