Common Lisp:为什么在从文件读取时将符号包含在错误的包中?

rob*_*ips 9 common-lisp

首先,我对lisp很新,所以我可能只是遗漏了一些非常明显的东西.也就是说,我在我旁边打开Practical Common Lisp,并在下一个选项卡中打开CL Hyper Spec,并且无法解决此问题:

我正在尝试从文件中读取树,并使用以下代码将值分配给类中的插槽:

(defun load-char (file)
  (with-open-file (in file)
    (with-standard-io-syntax
      (let ((chr-in (read in))
            (chr (make-instance 'pc)))
        (mapcar #'(lambda (x) (setf (slot-value chr (car x)) (cdr x))) chr-in)
        chr))))
Run Code Online (Sandbox Code Playgroud)

当我最初一起攻击它并在cl-user包下运行时,一切都运行得很好 - 实际上,我为自己感到骄傲.当我将它与我的类定义以及新包中的一些辅助函数一起打包时,问题就出现了.我使用asdf加载了包,然后用来(in-package :package-name)更改我的REPL的活动包.

现在,当我运行时,(load-char "/path/to/file")我得到一个错误,指出COMMON-LISP-USER::ID(ID是我的pc类中的第一个插槽)不存在,所以我写这个是为了看看我在读取文件时实际得到的内容:

(defun load-char-test (file)  
  (with-open-file (in file)  
    (with-standard-io-syntax  
      (let ((chr-in (read in))  
            (chr (make-hash-table)))  
        (mapcar #'(lambda (x) (setf (gethash (car x) chr) (cdr x))) chr-in)  
        (maphash #'(lambda (k v) (format t "~a: ~a~%" k v)) chr)
        chr))))
Run Code Online (Sandbox Code Playgroud)

然后在REPL中我做了(defparameter hsh (load-char-test "/path/to/file")),一切都没有错误,我的格式调用返回了我期望的(SLOT:VALUE).但当我这样做时,(gethash 'id hsh)它会返回NIL NIL.但是,当我这样做时,(gethash 'common-lisp-user::id hsh)它返回预期值.

所以,我正在阅读所有内容,但我的列表中的所有内容都是在COMMON-LISP-USER包下进行的,而不是我定义的包,我无法弄清楚原因.非常感谢帮助.

PS对不起,如果这篇文章不必要很长,我只想表明我实际上已经试图弄清楚这一点.

Xac*_*ach 13

创建的符号READ在包中实现,它是运行时的当前*PACKAGE*,而不是定义*PACKAGE*调用代码时的值READ.因此,一种选择是将您的阅读形式包装在一个绑定的形式*PACKAGE*,例如

(let ((*package* (find-package :package-name)))
  ...)
Run Code Online (Sandbox Code Playgroud)


Rai*_*wig 10

请注意,WITH-STANDARD-IO-SYNTAX将变量绑定*PACKAGE*到包CL-USER.

您需要*PACKAGE*将该宏中的变量绑定LET到您要使用的包.

另请注意,WITH-STANDARD-IO-SYNTAX将变量绑定*READ-EVAL*T.出于安全原因,通常不会出现默认情况.再次,通过LET绑定更改它.