我已经用quickproject为每个Xach的instructions.设置了一个hunchentoot项目--包在文件的顶部运行,hunchentoot在文件的后面启动。REPL也切换到我的包,但很明显hunchentoot没有在我的包中运行。这会在REPL和浏览器中的测试之间造成一些差异。例如,有一个函数在列表中查找一些东西,但hunchentoot从中获取了NILs,因为它使用了另一个包中的符号。
从对this related question的回答中我意识到,我可以将实习生符号的每一段代码包装成类似于
(let ((*package* (find-package :package-name)))
...)
这将在附带代码的持续时间内将*package*
变量设置为正确的包。
把它放在每个需要它的函数中,对我来说就像是一个混乱的黑客。
直觉告诉我,我应该能够像这样开始驼背:
(let ((*package* (find-package :package-name)))
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242)))
这样它就可以在*package*
设置为我喜欢的值的情况下整个运行,从而确保来自set服务器的调用所做的任何实战都是在我的包中完成的。它不起作用。Hunchentoot最终在cl-user下使用了一些东西,可能是因为使用了类似于上面链接中的WITH-STANDARD-IO-Hunchentoot这样的宏。
即使我能说服hunchentoot做我想做的事情,为什么我的“乱七八糟的黑客”仍然是更好的选择呢?
发布于 2013-08-15 08:34:00
当Hunchentoot在多线程中运行时,它的接受器和处理程序在非Lispwork实现上使用bordeaux-threads
生成的子线程中进行处理。出现这种情况的原因是,子线程的当前包变成了COMMON-LISP-USER
。
为了得到您想要的结果,您可以使子线程的当前包与调用线程的包相同,并实现与ONE-THREAD-PER-CONNECTION-TASKMASTER
任务管理器对应的START-THREAD
泛型函数。
请注意,您使用的是最新的Hunchentoot,它具有START-THREAD
泛型功能,我使用的是版本1.2.19。
(in-package :hunchentoot)
(defmethod start-thread ((taskmaster one-thread-per-connection-taskmaster) thunk &key name)
(let* (;; calling thread's current package
(package-name (package-name *package*))
;; initial special bindings passed to bordeaux threads
(initial-bindings `((*package* . (find-package ,package-name)))))
;; making child thread passing initial special bindings
(bt:make-thread thunk :name name :initial-bindings initial-bindings)))
发布于 2013-03-22 15:05:05
这不是Hunchentoot特定的问题,而是与Common Lisp包有关。
您所看到的是,在您的代码中,*PACKAGE*
特殊变量并没有绑定到您自己的包。IN-PACKAGE
仅在编译和读取时更改*PACKAGE*
。当包中的函数在运行时被调用时,*PACKAGE*
不会重新绑定,而需要显式绑定。
当您使用INTERN
或FIND-SYMBOL
时,最好将包指定为参数。或者,您也可以自己绑定*PACKAGE*
。
尝试对此文件执行LOAD
命令以查看:
(defpackage :foo
(:use :cl))
(in-package :foo)
(defun test ()
(print *package*))
(in-package :cl-user)
(foo::test)
发布于 2013-03-22 16:25:42
常见的Lisp代码不能在包中“运行”。
有一些操作使用了默认的包。就像从文本流中读取符号一样:
CL-USER 1 > *package*
#<The COMMON-LISP-USER package, 56/64 internal, 0/4 external>
CL-USER 2 > (read-from-string "FOO")
FOO
3
CL-USER 3 > (describe (read-from-string "FOO"))
FOO is a SYMBOL
NAME "FOO"
VALUE #<unbound value>
FUNCTION #<unbound function>
PLIST NIL
PACKAGE #<The COMMON-LISP-USER package, 57/64 internal, 0/4 external>
或者像找到一个符号:
(find-symbol "FOO")
这些操作取决于变量cl:*package*
的值。
要确保这些操作(读取符号、查找符号、插入符号等)正在做您期望的事情,您可能想要:
*package*
变量设置或绑定到您希望(find-symbol "FOO")
并将*package*
设置为某个包。但您也可以通过将相应的包作为参数传递来调用(find-symbol "FOO" my-package)
。摘要:Common Lisp代码不“在包中运行”,但它使用变量*package*
作为与包相关的操作的默认包。在使用此机制时,您需要设置或绑定此变量。
https://stackoverflow.com/questions/15561527
复制相似问题