Shammer's Philosophy

My private adversaria

Lisp で多重ロードをしないようにする

概要

CLHS: Function PROVIDE, REQUIREによれば、どうやら provide と require を使用するようだ。言われてみればよく見かける関数だ。provide でモジュールリストを確認し、存在しなければモジュールリストに対象モジュールを追加する。そして、require はモジュールリストにロード対象のモジュールがあるかを確認し、ある場合は即座に終了、なければそのままロード、という感じだ。全体の流れとしては、

  1. require でモジュールAをロードしようとする
  2. モジュールAが初めてロードされるときに自身をモジュールリストに追加
  3. 追加後に関数等がロードされる
  4. 別のところからモジュールAがロードされる
  5. モジュールリストにはすでにモジュール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
?