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

时间:2011-02-22 17:10:10

标签: 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))))

当我最初一起攻击它并在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))))

然后在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包下进行的,而不是我定义的包,我无法弄清楚原因。非常感谢帮助。

P.S。很抱歉,如果这篇文章不必要很长,我只是想表明我实际上已经试图自己解决这个问题。

2 个答案:

答案 0 :(得分:13)

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

*PACKAGE*

答案 1 :(得分:10)

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

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

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