5

私はDebiansqueezeでSBCL1.0.56を使用しており、cl-swank / slime 1:20120420-2(Debianバージョン番号)を使用しています。これらはすべて、unstableの現在のバージョンです。

サードパーティのCLパッケージのロードで問題が発生しています。DebianでCLを使用するためのドキュメント(そして実際にLinuxでのより一般的なCLの使用法のドキュメント)は大雑把で矛盾していて時代遅れなので、私が知っていることを要約します。これが私がいるところです。

Debianはバイナリパッケージ(例、cl-split-sequence)をにインストールします /usr/share/common-lisp/source。分割シーケンスの場合、これは /usr/share/common-lisp/source/cl-split-sequenceです。

.asdファイル(ここ /usr/share/common-lisp/source/cl-split-sequence/split-sequence.asd)は、私が理解しているように、バージョンと依存関係についてCL実装に指示を与えます。

;;; -*- Lisp -*- mode
(defpackage #:split-sequence-system (:use #:cl #:asdf))
(in-package :split-sequence-system)

(defsystem :split-sequence
    :version "20011114.1"
    :components ((:file "split-sequence")))

これで、スライムを実行するときに、REPLで次の2行を入力しても問題なく機能します

(require :split-sequence)
(split-sequence:SPLIT-SEQUENCE  #\, "foo,bar")

(require :split-sequence)呼び出しは(私が思うに)SBCL内のASDFの組み込みコピーを呼び出します。これはおそらく。を調べますsplit-sequence.asd。これはおそらくSBCL固有です。Debianマニュアルの第3章-ライブラリのCommonLispを参照してください。このページは、私が出会ったものと同じくらい便利で詳細であり、CLC(Common Lisp Controller)を頻繁に参照していますが、Debianはこれから離れつつあるようです。私が完全には理解していないCommonLispControllerの再設計を参照してください 。とにかく、CLCを使用するための文書化されたコマンドはどれも私には機能しません。ただし、CLCはDebianでも引き続き利用できます。また、ユーザーのメーリングリストは機能していません。Clc-usersアーカイブを参照してください。

初めて(require :split-sequence)呼び出され、コンパイルされ、(私のシステムでは、おそらくDebian固有の)結果faslがに配置されます

~/.cache/common-lisp/sbcl-1.0.56.0.debian-linux-x86/usr/share/common-lisp/source/cl-split-sequence/split-sequence.fasl

つまり、ファイルは元のソースの場所を反映したファイルシステムのキャッシュの下に配置されます。明らかな問題は、システムがパッケージを探す場所をどのように知るかということです。これは私がよくわからないことの1つです。ASDF Debianパッケージの一部であるで検索パスを指定する必要があるよう /etc/common-lisp/source-registry.conf.dですが、最も近いのは 01-common-lisp-controller.conf、です。

(:directory  #p"/usr/share/common-lisp/systems/")

多分これはどこかに配線されていますが、私は知りたいです。

とにかく、このASDFファイルがキャッシュに入ると、再度コンパイルされることはありませんが、スライムの起動後、もう一度コンパイルしない限り、REPLはそれを認識しません require

さて、線を引くと

(require :split-sequence)
(split-sequence:SPLIT-SEQUENCE  #\, "foo,bar")

たとえば、ファイルで、seq.lispCc Ckを使用してREPLにロードすると、エラーとトレースバックが発生します。

The name "SPLIT-SEQUENCE" does not designate any package.
   [Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]

したがって、パッケージが正しくロードされていないと結論付けます。私は次のようなバリエーションを試しました

(asdf:oos 'asdf:load-op :split-sequence)

(asdf:load-system :split-sequence)

しかし、サイコロはありません。奇妙なことに、私たちがちょうどラインを持っていると仮定します

(require :split-sequence)

ファイル内-require.lispわかりやすくするためにこれを呼び出します。次に、ロード require.lispしてもエラーは発生せず、次のように入力します

(split-sequence:SPLIT-SEQUENCE  #\, "foo,bar")

REPLで動作します!ただし、をロードrequire.lispしないと、前の行を入力してもREPLでは機能しません。

では、結論として、スクリプトでパッケージを正常にロードするにはどうすればよいでしょうか。ASDFが/usr/share/common-lisp/source/場所を見つける方法について、上記の問題にも興味がありますが、それは副次的な問題です。

4

2 に答える 2

5

C-c C-kソース ファイルをコンパイルし、コンパイルされたファイルをロードします。

Lisp ソース ファイルには、定義と呼び出しが含まれています。ファイル コンパイラは、ファイルを調べてコードを作成します。しかし、それは実行しません。

ファイルに への呼び出しが含まれている場合、REQUIREコンパイル中に実行されません。後でコンパイルされたファイルをロードすると実行されます。ファイル内の次の Lisp フォームが、 への呼び出し後に使用できるパッケージを使用している場合、はまだ実行されていないREQUIREため、コンパイル中に存在しません。したがって、コンパイル中の読み取り中にエラーが発生します。REQUIRE

それには基本的に2つの解決策があります。

  • REQUIRE必要な機能を使用して特定のファイルをコンパイルする前に、必要なすべての操作を実行します。
  • REQUIREコンパイル中にステートメントを実行します。ここでEVAL-WHEN :COMPILE-TOPLEVEL、コンパイル中にサブフォームを実行するようにコンパイルに指示します。

#+:sbcl(foo)(foo) は:SBCL、リストにシンボルが存在する場合にのみ読み取られることを意味しますCL:*FEATURES*。これは、コンパイラがこのコードを SBCL の場合にのみ認識するようにするために使用されます。

Common Lisp コードのコンパイルでは、次の理由により、準備にもっと注意が必要です。

  • ファイルのコンパイル中に Lisp コードを実行して、ファイル コンパイラの動作を変更することができます。

  • ソース コードで使用されるパッケージ (シンボルの名前空間) は、ファイル コンパイラのリーダーに認識される必要があります。

于 2012-05-11T06:30:51.253 に答える
1

次の投稿、ザック ビーンのブログ - Making a small Common Lisp projectに出くわしました。そこには、 http://common-lisp.net/~loliveira/ediware/ediware.lispへのリンクがありました。

そのファイルの先頭にあるコードをコピーすると機能します。したがって、このファイルに対してスライムで Cc Ck をsplit-sequence実行すると、コードがロードされて実行されますint (split-sequence:SPLIT-SEQUENCE #\, "foo,bar"))

#+:sbcl
(eval-when (:compile-toplevel :load-toplevel :execute)
  (require :asdf))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (asdf:oos 'asdf:load-op :split-sequence))

(defpackage #:seq
  (:use #:cl #:split-sequence))
(in-package #:seq)

(print (split-sequence:SPLIT-SEQUENCE  #\, "foo,bar"))

しかし、私はこれらの魔法の呪文が何をするのか分かりません. おそらく別の答えで、誰かが説明したいと思いますか?これは質問への回答であるため、回答に入れていますが、なぜ機能するのか理解できないため、完全ではありません。このスクリプトの説明を喜んで受け入れます。

于 2012-05-11T06:19:06.877 に答える