パッケージは、symbolをグループ化するための区分された名前の付いた空間を与える。
複数のプログラマが要求されるような膨大なソフトウェアシステム
を開発しようとするとき、symbol(関数および変数名)が重複する問題を減少させるために
Common Lispでパッケージシステムが生まれた。
それぞれのパッケージは、内部symbolと外部symbolを持つ。
パッケージの中でsymbolが作成されたとき、いつでも内部symbolとなる。
exportを使用することにより外部symbolにすることができる。
異なったパッケージの外部symbolは、symbolの前にパッケージ名とコロン(:)を
つけることにより参照することができる。例えば、x:*display*となる。
他のパッケージの内部symbolを参照する場合には、sys::free-threadsのように
ダブルコロン(::)を使用する。
前にパッケージ名をつけることを省略するためには、importを用いる。
その上、use-packageを使用すれば、他のパッケージの全ての
外部symbolをimportすることができる。
symbolをexportあるいはimportするとき、あらゆるパッケージ内の
全てのsymbolが独自の
print-nameを持つ必要があるため、symbol名の重複を発見することができる。
shadowは、パッケージからsymbolを仮想的に削除することにより、
存在するsymbolと同じ名前のsymbolを作成することができる。
Euslispは次の8つのパッケージを定義する。
- lisp:
- 全てのlisp関数、マクロ、定数、など
- keyword:
- キーワードsymbol
- unix:
- UNIXシステムコールとライブラリ関数
- system:
- システム管理または危険な関数; nicknames=sys,si
- compiler:
- EusLispコンパイラ; nicknames=comp
- user:
- ユーザー領域
- geometry:
- 幾何学クラスとその関数
- xwindow:
- X-windowインターフェース; nickname=x
これらのパッケージとユーザー定義パッケージは、システムの
package-listに繋げられている。
それは、list-all-packagesよって得ることができる。
それぞれのパッケージは、内部および外部symbolを探索・位置付けするために2つの
ハッシュテーブルを管理する。
また、パッケージは、その名前(stringまたはsymbol)とnick nameのリストと
そのパッケージが使う他のパッケージリストを記憶している。
*package*は、読み込み・印刷のための主なパッケージを持つ
グローバル変数である。
もし*package*がuser:でないならば、
top-levelプロンプトは、現在のパッケージを示すためにmypkg:eus$のように変更される。
*lisp-package* [定数]
-
- Lispパッケージ。
*user-package* [定数]
-
- ユーザーパッケージ。
*unix-package* [定数]
-
- UNIXパッケージ。
*system-package* [定数]
-
- システムパッケージ。
*keyword-package* [定数]
-
- キーワードパッケージ。
find-symbol string &optional (package *package*) [関数]
-
-
packageのなかでprint-nameとしてstringをもつsymbolを
見つける。
もし見つかったとき、そのsymbolが返され、そうでないときNILが返される。
make-symbol string [関数]
-
-
stringで示される名前の新しい収容されていないsymbolを作る。
intern string &optional (package *package*) (klass symbol) [関数]
-
-
stringと同じprint-nameのsymbolを見つけようとする。
もし探索成功のとき、そのsymbolが返される。
もし失敗したとき、stringというprint-nameを持つsymbolが新しく作られ、
packageの中におかれる。
list-all-packages [関数]
-
-
今までに作られた全てのパッケージのリストを返す。
find-package name [関数]
-
-
パッケージの名前またはnicknameがnameと同じものを探す。
make-package name &key :nicknames (:use '(lisp)) [関数]
-
-
nameで示される名前の新しいパッケージを作る。
nameは、stringあるいはsymbolでよい。
もしパッケージが既に存在している場合、エラーが報告される。
in-package pkg &key :nicknames (:uses '(lisp)) [関数]
-
-
現在のパッケージ(*pacakge*の値)を
pkgに変える。
package-name pkg [関数]
-
-
pkgパッケージの名前を文字列として返す。
package-nicknames pkg [関数]
-
-
pkgのnicknameのリストを返す。
rename-package pkg new-name &optional new-nicknames [関数]
-
-
pkgの名前をnew-nameに変更し、そのnicknameを
new-nicknamesに変更する。
それらは、symbolかstringまたはsymbolかstringのリストのどれでも可能である。
package-use-list pkg [関数]
-
-
pkgで使用されるパッケージリストを返す。
packagep pkg [関数]
-
-
もしpkgがパッケージのときTを返す。
use-package pkg &optional (curpkg *package*) [関数]
-
-
pkgをcurpkgのuse-listに付け加える。
一旦追加すると、pkgのなかのsymbolは、パッケージの前置詞なしで
curpkgを見ることが可能になる。
unuse-package pkg &optional (curpkg *package*) [関数]
-
-
curpkgのuse-listからpkgを削除する。
shadow sym &optional(pkg *package*) [関数]
-
-
存在するsymを隠すことによって、
pkg内に内部symbolを作る。
export sym &optional (pkg *package*) [関数]
-
-
symは、symbolかsymbolのリストである。
exportは、symを他のパッケージから
外部symbolとしてアクセス可能とする。
実際に、symは、pkgのなかの外部symbolとして記録される。
もしsymbolがexportされると、パッケージマークとしてsingle colon ":"を使って
アクセス可能となる。これに対して、exportされていないsymbolはdouble colon "::"
で得られる。
そのうえ、exportされたsymbolは、
use-packageを使用したり、パッケージにimportされたとき、コロンの
必要がない。
symbolがexportされたかどうかは、それぞれのsymbolにでなくそれが収容されている
パッケージに属性付けられる。
それで、symbolは1つのパッケージの内部にあり、その他の外部となる。
exportは、pkgが使用している他のパッケージの中の
symbol名とsymが重複していないかどうかを検査する。
もしsymと同じprint nameをもつsymbolがあったならば、
"symbol conflict"とエラーを報告する。
unexport sym &optional pkg [関数]
-
-
もしsymがpkgの外部symbolであったならば、unexportされ、
内部symbolとなる。
import sym &optional (pkg *package*) [関数]
-
-
symは、symbolまたはsymbolのリストである。
importは、他のパッケージで定義されたsymbolを
pkgからパッケージの前置詞なしで内部symbolとして見えるようにする。
もしsymと同じprint-nameを持ったsymbolが既にあったとき、
"name conflict"とエラーを報告する。
do-symbols (var pkg) &rest forms [マクロ]
-
-
pkgにおいて、(内部あるいは外部)symbolに対して繰り返しをする。
そのときのformsの評価が返される。
do-external-symbols (var pkg) &rest forms [マクロ]
-
-
pkgにおいて、外部symbolに対して繰り返しをする。
そのときのformsの評価が返される。
do-all-symbols (var [result]) &rest forms [マクロ]
-
-
全てのパッケージにおいて、symbolに対して繰り返しをする。そのときのformsの評価が返される。
もし、1つ以上のパッケージの中にそのsymbolが現れたならば、formsは、
1度以上評価される。
2016-04-05