11

私は画像ベースの言語のアイデアが大好きで、最近は sbcl を介して Common Lisp をいじっています。仮想マシンのイメージを保存およびロードバックできることで、そのイメージで実行されているアプリケーションまたはアプリケーションのセットを進化させる方法について、いくつかの場所で読みました。

コードをイメージにロードして実行する方法を理解しました。スライムはこの種のことを非常に素晴らしいものにしますが、私の質問は次のとおりです。イメージで定義されている関数をどのように確認できますか? 関数を実行してから数日または数か月後に関数を更新したいのですが、名前を思い出せないとします。イメージで定義されたコードまたは関数の名前だけにアクセスする方法はありますか?

今、私はコードをソースに書き出し、repl を介してロードするので、そこにコピーがありますが、これは明らかな機能のようです。

4

2 に答える 2

13

Common Lisp にはパッケージの概念があります。パッケージはシンボルの一種のレジストリであり、シンボルの名前空間として使用されます。すべてのパッケージのリストを Common Lisp に問い合わせることができます。

CL-USER 1 > (list-all-packages)
(#<The SQL-COMMON package, 0/4 internal, 28/32 external>
 #<The LOOP package, 245/256 internal, 3/4 external>
 #<The COMM package, 0/4 internal, 940/1024 external>
 #<The REG package, 41/64 internal, 0/4 external>
 ...)

各パッケージは、インターンされたシンボルを何らかのデータ構造に格納します。どのシンボルがパッケージにインターンされているかを Common Lisp に問い合わせることができます。

CL-USER 2 > (loop for symbol being
                each external-symbol in (find-package "COMMON-LISP")
             collect symbol)
(MAKE-ARRAY INVOKE-DEBUGGER STRING-TRIM ...)

これを簡単にするために、Common Lisp には関数 APROPOS と APROPOS-LIST が用意されています。

CL-USER 3 > (apropos "MAKE-LOCK")
MP::INTERNAL-MAKE-LOCK (defined)
MP:MAKE-LOCK (defined)
WWW-UTILS:MAKE-LOCK (defined)
MAKE-LOCK
RESOURCES::MAKE-LOCK (defined)
MINIPROC:MAKE-LOCK (defined)

関数、クラスなどは、シンボルを識別子として使用します。また、シンボルがどの機能を表しているかを尋ねることもできます。

CL-USER 4 > (symbol-function 'www-utils:make-lock)
#<Function WWW-UTILS:MAKE-LOCK 41E006A69C>

Common Lisp が関数の定義を記録することもあります。次に、関数 FUNCTION-LAMBDA-EXPRESSION を使用して「it」を取得できます。

CL-USER 5 > (defun foo (a) (* (sin a) a))
FOO

CL-USER 6 > (pprint (function-lambda-expression 'foo))

(LAMBDA (A)
  (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 41403151C3>))
  (DECLARE (LAMBDA-NAME FOO))
  (* (SIN A) A))

しかし、最近の Common Lisp の実装では通常、記録された定義を使用せず、各 Lisp 構造のソースの場所を記録します。

ほとんどの Common Lisp 実装は、実装固有の方法でソースの場所を追跡できます。

Common Lisp 標準では、関数 ED が定義されています。

CL-USER 7 > (ed 'www-utils:make-lock)

これにより、エディター (内部または外部) が呼び出され、その関数のソース コードが開きます。それを機能させるために、Common Lisp は各関数のソースの場所を追跡する必要があります。次に、編集者はそのソースにアクセスできる必要があります。記録される場所が絶対パス /Users/joswig/lisp/utils.lisp である場合があります。エディターがそのファイルを開きたい場合は、アクセスできる必要があります。ただし、論理パス名を使用することもできますhttp:server;utils.lisp のように。これは、実際の物理パス名に変換されます。この変換は後で構成できます。したがって、Lisp を異なるパス名を持つ別のマシンに移動し、論理パス名 HTTP を構成すると、Lisp は、ファイル システム構造が異なる別のマシン上にある場合でも、すべてのソース コードを見つけることができます。したがって、それを機能させるには、いくつかの構成が必要になる場合があります。しかし、これは非常に便利な機能であり、広く使用されています。

ソースコードの記録とソースの場所の記録がどのように機能するかは実装に依存し、開発環境と組み合わせたそれぞれの Lisp の機能です。より良いLisp 実装には、この分野で多くの機能があります。

于 2011-02-19T13:24:44.630 に答える
5

You can also use do-symbols or do-external-symbols if you prefer:

example:

>> (do-external-symbols (s (find-package :foo-package)) (print s))

FOO-PACKAGE:XXX
FOO-PACKAGE:YYY
FOO-PACKAGE:ZZZ
NIL

Where XXX, YYY & ZZZ are all external symbols in the package :foo-package.

于 2011-02-23T00:33:42.980 に答える