一个合法的用例是记住程序的构建时间。将以下代码保存在文件“foo.lisp”中:
(in-package :cl-user)
(defvar *compilation-time* nil)
(eval-when (:compile-toplevel)
(setf *compilation-time* (multiple-value-bind (s m h)
(decode-universal-time (get-universal-time))
(format nil "~D:~D:~D" h m s))))
(format t "Built at: ~A~%" *compilation-time*)
(defvar *compilation-path* nil)
(eval-when (:compile-toplevel)
(setf *compilation-path* *compile-file-pathname*))
(format t "Built from: ~A" *compilation-path*)
在新的 sbcl 会话中:
# sbcl --noinform --no-userinit
* (compile-file "foo")
; compiling file "/tmp/common-lisp/foo.lisp" (written 18 APR 2024 05:21:25 PM):
; wrote /tmp/common-lisp/foo.fasl
; compilation finished in 0:00:00.006
#P"/tmp/common-lisp/foo.fasl"
NIL
NIL
* *compilation-time*
"17:33:20"
我的理解是,因为我编译了文件,所以评估了
:compile-toplevel
表格。因此,在 that sbcl 会话中,设置了 *compilation-time*
。但是,如果启动一个新会话,并加载已编译的 fasl 文件,*compilation-time*
为空!
# sbcl --noinform --no-userinit
* (load "foo.fasl")
Built at: NIL
Built from: NIL
T
*
显然,“foo.fasl”文件不记得它是什么时候构建的。
我的问题:是否可以让 fasl 文件真正记住编译时信息,并在以后的会话中引用这些信息?
当然,它应该如何运作?您的代码不会在加载时设置变量。
也许是这样的:
(defmacro updating-compilation-time ()
`(setf *compilation-time*
,(multiple-value-bind (s m h)
(decode-universal-time (get-universal-time))
(format nil "~D:~D:~D" h m s))))
(updating-compilation-time)