Lisp で多重ロードをしないようにする
概要
CLHS: Function PROVIDE, REQUIREによれば、どうやら provide と require を使用するようだ。言われてみればよく見かける関数だ。provide でモジュールリストを確認し、存在しなければモジュールリストに対象モジュールを追加する。そして、require はモジュールリストにロード対象のモジュールがあるかを確認し、ある場合は即座に終了、なければそのままロード、という感じだ。全体の流れとしては、
- require でモジュールAをロードしようとする
- モジュールAが初めてロードされるときに自身をモジュールリストに追加
- 追加後に関数等がロードされる
- 別のところからモジュールAがロードされる
- モジュールリストにはすでにモジュールAがあるのでそこでロード終了
という流れだ。ちなみに、require ではロードしたいパッケージとそれが記述されたソースコードのPathを引数で渡すことができる。指定されたソースコードに該当パッケージがない場合は何もされない。
サンプル
モジュール側
(provide 'mylib1) (defpackage "MYLIB1") (in-package mylib1) (export 'hello) (defun hello () (format t "Hello! This is mylib1:hello.~%"))
ロードする側
? (require "MYLIB1" "lib1.lisp") "MYLIB1" ("MYLIB1") ? (mylib1:hello) Hello! This is mylib1:hello. NIL ? (defun hello () (format t "Hello!~%")) HELLO ? (hello) Hello! NIL ? (mylib1:hello) Hello! This is mylib1:hello. NIL ? (require "MYLIB2" "lib1.lisp") "MYLIB2" NIL ? (find-package 'mylib2) NIL ?