首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >更改hunchentoot的当前包

更改hunchentoot的当前包
EN

Stack Overflow用户
提问于 2013-03-22 10:06:45
回答 3查看 204关注 0票数 0

我已经用quickproject为每个Xach的instructions.设置了一个hunchentoot项目--包在文件的顶部运行,hunchentoot在文件的后面启动。REPL也切换到我的包,但很明显hunchentoot没有在我的包中运行。这会在REPL和浏览器中的测试之间造成一些差异。例如,有一个函数在列表中查找一些东西,但hunchentoot从中获取了NILs,因为它使用了另一个包中的符号。

从对this related question的回答中我意识到,我可以将实习生符号的每一段代码包装成类似于

代码语言:javascript
运行
复制
(let ((*package* (find-package :package-name)))
  ...)

这将在附带代码的持续时间内将*package*变量设置为正确的包。

把它放在每个需要它的函数中,对我来说就像是一个混乱的黑客。

直觉告诉我,我应该能够像这样开始驼背:

代码语言:javascript
运行
复制
(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做我想做的事情,为什么我的“乱七八糟的黑客”仍然是更好的选择呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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。

代码语言:javascript
运行
复制
(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)))
票数 1
EN

Stack Overflow用户

发布于 2013-03-22 15:05:05

这不是Hunchentoot特定的问题,而是与Common Lisp包有关。

您所看到的是,在您的代码中,*PACKAGE*特殊变量并没有绑定到您自己的包。IN-PACKAGE仅在编译和读取时更改*PACKAGE*。当包中的函数在运行时被调用时,*PACKAGE*不会重新绑定,而需要显式绑定。

当您使用INTERNFIND-SYMBOL时,最好将包指定为参数。或者,您也可以自己绑定*PACKAGE*

尝试对此文件执行LOAD命令以查看:

代码语言:javascript
运行
复制
(defpackage :foo
  (:use :cl))

(in-package :foo)

(defun test ()
  (print *package*))

(in-package :cl-user)

(foo::test)
票数 3
EN

Stack Overflow用户

发布于 2013-03-22 16:25:42

常见的Lisp代码不能在包中“运行”。

有一些操作使用了默认的包。就像从文本流中读取符号一样:

代码语言:javascript
运行
复制
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>

或者像找到一个符号:

代码语言:javascript
运行
复制
(find-symbol "FOO")

这些操作取决于变量cl:*package*的值。

要确保这些操作(读取符号、查找符号、插入符号等)正在做您期望的事情,您可能想要:

  • *package*变量设置或绑定到您希望
  • 显式将该包传递给操作的包。您可以调用(find-symbol "FOO")并将*package*设置为某个包。但您也可以通过将相应的包作为参数传递来调用(find-symbol "FOO" my-package)

摘要:Common Lisp代码不“在包中运行”,但它使用变量*package*作为与包相关的操作的默认包。在使用此机制时,您需要设置或绑定此变量。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15561527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档