Posted 2009-12-05 10:56:00 GMT
今回は、KMRCLのmacros.lispの中からDEFCONSTANT*です。
DEFCONSTANT*は割と定番のマクロな気がします。
定義は、
(defmacro defconstant* (sym value &optional doc) "Ensure VALUE is evaluated only once." `(defconstant ,sym (if (boundp ',sym) (symbol-value ',sym) ,value) ,@(when doc (list doc))))という感じで、変数を再度DEFCONSTANTしてしまうのを防ぐマクロです。
;; /tmp/foo.lispというファイル (DEFCONSTANT +CONST+ 42)
;; SBCL (COMPILE-FILE "/tmp/foo.lisp") +CONST+ ;⇒ 42
;; Allegro CL (COMPILE-FILE "/tmp/foo.lisp") +CONST+ ;>>> Attempt to take the value of the unbound variable `+CONST+'.というわけなので、SBCLだとファイルをロードしなくてもDEFCONSTANTの再定義でぶつかることがあります。
The constant +CONST+ is being redefined (from 42 to 43) [Condition of type DEFCONSTANT-UNEQL] See also: Common Lisp Hyperspec, DEFCONSTANT [:macro] SBCL Manual, Idiosyncrasies [:node]というようなエラーはSBCLだとライブラリを読み込むときに良く遭遇しますが、こういうケースをDEFCONSTANT*だと回避できるわけですね。