在CommonLisp中,是否可以让编译后的代码记住编译时信息并在运行时引用它

问题描述 投票:0回答:1

一个合法的用例是记住程序的构建时间。将以下代码保存在文件“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 文件真正记住编译时信息,并在以后的会话中引用这些信息?

compilation common-lisp eval-when
1个回答
0
投票

当然,它应该如何运作?您的代码不会在加载时设置变量。

也许是这样的:

(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)
© www.soinside.com 2019 - 2024. All rights reserved.