% Macro DEFPACKAGE
Macro DEFPACKAGE
defpackage
defined-package-name [[option]] => package
option::= (:nicknames nickname*)* |
(:documentation string) |
(:use package-name*)* |
(:shadow {symbol-name}*)* |
(:shadowing-import-from package-name {symbol-name}*)* |
(:import-from package-name {symbol-name}*)* |
(:export {symbol-name}*)* |
(:intern {symbol-name}*)* |
(:size integer)
defined-package-name - 文字列指定子
package-name - パッケージ指定子
nickname - 文字列指定子
symbol-name - 文字列指定子
package - package-nameという名前のパッケージ
defpackage
は指定されたパッケージを作成し、
そのパッケージを返却します。
もしdefined-package-nameがすでに存在しているパッケージを示していたら、 その名前とパッケージのマッピングの対応は変更されません。 もし新しい定義がパッケージの現在の状況と変わっていたときは、 その結果は定義されていません。 実装によっては、新しい定義を反映するよう、 既存のパッケージを修正するか選択するかもしれません。 もしdefined-package-nameがシンボルのときは、その名前が使われます。
標準のオプションを下記に示します。
:nicknames
:nicknames
の引数はパッケージのニックネームに指定した名前をセットします。
:documentation
:documentation
の引数は、ドキュメント文字を指定します。
それはパッケージのドキュメント文字に割り当てます。
ひとつのdefpackage
フォームに
最大ひとつの:documentation
オプションを記載することができます。
:use
:use
引数は、package-nameという名前のパッケージが継承するように、
パッケージに対して設定を行います。
:shadow
:shadow
引数は、symbol-namesという名前のシンボルを
パッケージ内に作成するように定義します。
それらのシンボルは、shadow
によるもののように
効果的にshadowing
シンボルのリストに追加されます。
:shadowing-import-from
find-symbol
によるもののように検索が実行されます)。
その結果のシンボルがそのパッケージ内にimport
されるように定義し、
shadowing-import
によるもののように
shadowing
シンボルのリストに配置されます。
:import-from
import
されます。
どのような場合でも、定義されているパッケージ以外の
パッケージでシンボルを作成してはいけません。
:export
export
します。
継承されるシンボルが作成されるのではなく使用されるとき、
:export
オプションは:use
オプションと互いに作用します。
import
されるシンボルが作成されるのではなく使用されるとき、
:export
オプションは:import-from
および
shadowing-import-from
オプションと互いに作用します。
もし:export
オプションの引数が
use-package
によって(継承された)内部シンボルとして
アクセス可能であるとき、
symbol-nameという名前のシンボルは、
最初に定義されているパッケージにimport
され、
そのあとそのパッケージからexport
されます。
:intern
:intern
オプションは:use
オプションと互いに作用します。
:size
:size
オプションの引数は、予想されるパッケージ内の
シンボルの数の近似値を宣言します。
これはただの効率化のヒントであり、実装によっては無視されるかもしれません。
defpackage
フォームに現れるオプションの順番は無関係です。
それらが実行される順番は下記のようになります。
:shadow
と:shadowing-import-from
:use
:import-from
と:intern
:export
:use
オプションが処理されるときに
衝突による偽りの名前をブロックする必要があるため、
最初にshadow
を確立させます。
:use
オプションが次に実行されるので、
:intern
と:export
オプションが継承されたシンボルを普通に参照できます。
:export
オプションが最後に実行されるとき、
それは他のオプションの何かによって作成された
シンボルを参照することができます。
とくにshadowing
シンボルとimport
シンボルを
外部シンボルにすることができます。
もしdefpackage
フォームがトップレベルフォームとして現れたとき、
ロード時にこのマクロによって実行される全ての通常のアクションは、
コンパイル時にもまた実行されなければいけません。
(defpackage "MY-PACKAGE"
(:nicknames "MYPKG" "MY-PKG")
(:use "COMMON-LISP")
(:shadow "CAR" "CDR")
(:shadowing-import-from "VENDOR-COMMON-LISP" "CONS")
(:import-from "VENDOR-COMMON-LISP" "GC")
(:export "EQ" "CONS" "FROBOLA")
)
(defpackage my-package
(:nicknames mypkg :MY-PKG) ; Common Lispの大文字小文字の慣習を思い出そう
(:use common-lisp) ; シンボルの慣習
(:shadow CAR :cdr #:cons)
(:export "CONS") ; これはshadowされる
)
存在するパッケージ
:nicknames
で指定したひとつが
すでに既存のパッケージで参照されていたときは、
型package-error
のエラーが発生します。
もし:size
か:documentation
が複数現れていたときは
型program-error
のエラーが発生します。
実装が拡張のオプションを許すとき、
あるオプションが実際にはその実装でサポートされていないものとして現れたとき、
型program-error
のエラーが発生します。
オプションの:shadow
, :intern
, :import-from
, :shadowing-import-from
に
指定されたsymbol-name引数の集まりは、
全てが互いに素でなければいけません。
加えて、:export
と:intern
のに指定されたsymbol-name引数は
互いに素でなければいけません。
この文脈での互いに素というのは、
2つのsymbol-namesが互いにstring=
で
等しくないものとして定義されます。
このどちらかの条件に違反していたときは、
型program-error
のエラーが発生します。
:shadowing-import-from
と:import-from
オプションについて、
package-nameという名前のパッケージに
引数symbol-namesのうちのひとつが
アクセス可能なシンボルではないとき、
修正可能な型package-error
のエラーが発生します。
名前の衝突エラーは、
make-package
, use-package
, import
, export
の
基本的な呼び出しによって捕捉されます。
11.1. パッケージの説明をご確認ください。
documentation
,
11.1. パッケージの説明,
3.2. コンパイル
いくつかの他のパッケージの作成に続くdefpackage
の呼び出しで、
:import-from
か:shadowing-import-from
オプションを用いて
それらのシンボルをアクセス可能な状態にしたいものの
外部シンボルにする必要はないときは、
:intern
オプションが便利です。
パッケージの全体の定義を一か所に配置し、
全てのパッケージの定義のプログラムを
ひとつのファイルにしたいとき
defpackage
の使用をお勧めします。
このファイルは、
これらのパッケージに依存する他の何かを
ロードしたりコンパイルしたりする前に
ロードすることができます。
このようなファイルは
初期状態の異常を回避するために、
COMMON-LISP-USER
パッケージで読み込むことができます。
defpackage
は、2つの「互いに再帰的」なパッケージを
作成するときには使えません。
例えば次の通り。
(defpackage my-package
(:use common-lisp your-package) ;最初にyour-packageの存在が必要
(:export "MY-FUN"))
(defpackage your-package
(:use common-lisp)
(:import-from my-package "MY-FUN") ;最初にmy-packageの存在が必要
(:export "MY-FUN"))
しかし、defpackage
をより標準的に使ったあとで、
use-package
、import
、export
などの
パッケージに影響を与える関数を使って、
そのようなリンクを確立することを妨げるものは何もありません。
defpackage
のマクロ展開は、
通常は名前を文字列に正規化するので、
ソースファイルにランダムなシンボルが含まれるdefpackage
フォームが
配置されているようなときでさえ、
コンパイルファイルにはただ文字列だけが配置されます。
よく追加で実装依存のオプションに、
キーワードそれ自身のフォームで(keyword T)
という
リストの省略形を表すことがあります。
この構文は、これをサポートしていない実装では、
認識できないオプションとして適切に報告されるべきです。