Common Lisp:为什么从文件中读取符号时将符号插入错误的包中? [英] Common Lisp: Why is cl lnterning symbols to the wrong package when reading from file?

查看:82
本文介绍了Common Lisp:为什么从文件中读取符号时将符号插入错误的包中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我对Lisp非常陌生,因此有可能我只是想念一些非常明显的东西。就是说,我旁边已打开实用通用Lisp,并且在下一个选项卡中打开了CL Hyper Spec,并且无法解决此问题:

First, I am very new to lisp, so it is possible that I'm just missing something very obvious. That said, I have Practical Common Lisp open next to me and the CL Hyper Spec open in the next tab, and have been unable to solve this issue:

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

I am trying to read a tree from a file, and assign values to slots in a class using this code:

(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的有效程序包。

When I originally hacked this together and ran it under the cl-user package everything worked perfectly -- I was quite proud of myself, actually. The problem started when I packaged this along with my class definition and a few helper functions in a new package. I loaded the package using asdf, then used (in-package :package-name) to change my REPL's active package.

现在当我运行(load-char / path / to / file)时,我得到一个错误说 COMMON-LISP-USER :: ID (ID是我的pc类中的第一个插槽)不存在,所以我写了这篇文章以查看我实际上在什么时候得到了什么我在以下位置读取文件:

Now when I run (load-char "/path/to/file") I get an error that says the COMMON-LISP-USER::ID (ID is the first slot in my pc class) does not exist, so I wrote this to see what I was actually getting when I read the file in:

(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))一切都没有错误,并且我的format调用返回的正是我期望(SLOT:VALUE)。但是,当我执行(gethash’id hsh)时,它会返回 NIL NIL 。但是,当我执行(gethash'common-lisp-user :: id hsh)时,它将返回期望值。

Then in the REPL I do (defparameter hsh (load-char-test "/path/to/file")) and everything goes without errors, and my format call returns exactly what I expect (SLOT: VALUE). But when I do a (gethash 'id hsh) it returns NIL NIL. But, when I do (gethash 'common-lisp-user::id hsh) it returns the expected value.

所以,我读的一切都很好,但是列表中的所有内容都被COMMON-LISP-USER包而不是我定义的包监禁了,我不知道为什么。非常感谢您的帮助。

So, I'm reading in everything just fine, but everything in my list is being interned under the COMMON-LISP-USER package instead of the one I defined, and I cannot figure out why. Help is greatly appreciated.

P.S。抱歉,如果这篇文章过长,我只是想表明我实际上已经自己弄清楚了。

P.S. Sorry if this post is needlessly long, I just wanted to show that I had actually tried to figure this out myself.

推荐答案

符号由 READ 创建的创建的程序将被包装在 current 值为 * PACKAGE * 的程序包中在运行时,定义了调用 READ 的代码时,值 * PACKAGE * 不具有。然后,一种选择是将阅读表格包装成绑定 * PACKAGE * 的形式,例如

Symbols created by READ are interned in the package that is the current value of *PACKAGE* at runtime, not the value *PACKAGE* had when the code that calls READ was defined. One option, then, is to wrap your reading forms in a form that binds *PACKAGE*, e.g.

(let ((*package* (find-package :package-name)))
  ...)

这篇关于Common Lisp:为什么从文件中读取符号时将符号插入错误的包中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆