0

Xach の指示に従って、quickproject を使用して hunchentoot プロジェクトをセットアップしました。In-package はファイルの先頭で実行され、hunchentoot はファイルの後半で開始されます。REPL も私のパッケージに切り替えられますが、hunchentoot が私のパッケージで実行されていないことは明らかです。これにより、REPL とブラウザーのテストの間に多少の不一致が生じます。たとえば、alist 内のいくつかのものを検索する関数がありますが、hunchentoot は別のパッケージのシンボルを使用しているため、そこから NIL を取得します。

この関連する質問への回答から、シンボルをインターンするすべてのコードを次のようなものでラップできることを認識しています

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

これ*package*により、同封されたコードの期間中、var が正しいパッケージに設定されます。

これを必要とするすべての機能にこれを配置することは、面倒なハックのように感じます。

直観によると、次のように hunchentoot を開始できるはずです。

(let ((*package* (find-package :package-name)))
  (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242)))

好みの値に設定して全体を実行*package*できるようにすることで、Web サーバーからの呼び出しによって行われるすべてのインターンがパッケージ内で確実に行われるようにします。うまくいきません。Hunchentoot は、おそらく上記のリンクのように WITH-STANDARD-IO-SYNTAX のようなマクロを使用したために、cl-user の下にインターンしてしまいます。

hunchentoot を説得して自分のやりたいことをやらせることができたとしても、「乱雑なハック」を行うほうがよい理由はありますか?

4

3 に答える 3

3

これは 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-22T07:05:05.243 に答える
3

Common 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*パッケージ関連の操作のデフォルト パッケージとして変数を使用します。このメカニズムを使用する場合は、この変数を設定またはバインドする必要があります。

于 2013-03-22T08:25:41.763 に答える