1

私が欲しかったのは、スワンクなしで起動したときに私のlispに影響を与えないスワンクの初期化ファイルをロードすることだけでした...

私は最初に ccl-init からロードされたファイルで #+swank (defun...) を試しました (これを ccl 1.10 + Windows で試しました)。

私の目的は、スワンクを開始するたびに :cl-user で単純な関数を定義することです。init.lisp ファイルをロードするためのおしゃれな add-hook が完成しました。cl-user で関数を定義したいので、init.lisp でこれを試しました。

(let ((current-package *package*))
  (in-package :cl-user)
  (defun cd (dir)
    (swank:set-default-directory
      (parse-namestring dir)))
  (in-package current-package))

さて、let の defun が許可されていたかどうかは覚えていませんが、lisp は文句を言いませんが、cur-pck シンボルが存在しないことを教えてくれます。パッケージを切り替えると、cur-pck のように見えますバインディングは範囲外になります。cur-pck は字句バインディングであり、字句領域内から到達可能で、パッケージから独立していると思っていましたが、間違っていますか?

なぜパッケージを切り替えるのですか? 初期化ポイントでこのファイルを swank からロードすると、いくつかの swank パッケージで何かが定義されると考えています。そのため、最初に cl-user に切り替えて、関数シンボルを定義し、元に戻して swank にそれをさせたいと思っていました。

この時点で、私は間違った角度から問題に取り組んでおり、より簡単な解決策を選択する必要があることを誰かに教えてもらう必要があると思います。

さらに、上記が完全に間違ったアプローチである場合の好奇心から、関数またはクロージャー内の別のパッケージでシンボルを定義する方法はありますか?

4

3 に答える 3

4

現在のパッケージとは異なるパッケージで関数を定義する場合は、名前に修飾記号を使用できます

(defun cl-user::cd (dir)
    (swank:set-default-directory
      (parse-namestring dir)))

バインディングが「失われる」ことはありません。自分でテストする(princ cur-pck)には、パッケージ内のフォームの前に追加します。

評価してみる(in-package *package*)と、コードがパッケージの切り替えに失敗する理由がわかります。パッケージ内マクロはその引数を評価しません。評価したいコードを提供するコードは次のとおりです。

(let ((cur-pck *package*))
  (in-package :cl-user)
  (defun cd (dir)
    (swank:set-default-directory
     (1+ 2)))
  (princ cur-pck)
  `(in-package ,cur-pck)) 

ただし、Rainer Joswig が彼の回答で指摘したように、インパッケージは既に読み取られたフォームには影響しないため、マクロとしても期待どおりに機能しません。

スタイルのつまらないものです。略語を使用せず、current-package と記述してください。

于 2015-08-21T04:09:58.963 に答える
2

IN-PACKAGE関数ではなくマクロです。コードの問題は、変数で示されるパッケージではなく、指定されたパッケージ(明らかに存在しない)(in-package cur-pck)に切り替えようとすることです。cur-pckCUR-PCK

でパッケージを一時的に設定できます

(let ((*package* (find-package :cl-user)))
  (defun cd (dir)
    ...))

しかし、繰り返しますが、あなたがやっていることを達成する最も簡単な方法は

(defun cl-user::cd (dir)
  ...)

これにより、現在のパッケージを設定する必要が完全になくなります。

于 2015-08-21T04:02:55.867 に答える