そのファイルのすべてのコンパイルは、load-op
のいずれかを実行する前に行われます。したがって、Lispが行をコンパイルするとき、パッケージを定義するを(sdl-examples:squashed)
実行していません。load-op
が実際に実行される前sdl-examples
にリーダーがそのsquashed
シンボルを見つける必要があるパッケージについて言及しないことで、これを回避できます。load-op
(funcall (symbol-function (intern (symbol-name '#:squashed)
(find-package (symbol-name '#:sdl-examples)))))
アイデアは、シンボル名からパッケージを計算し、関数に名前を付けるシンボルを検索し、名前を付けた関数をフェッチすることです。ただし、この方法では、パッケージが最初に読み取られたときではなく、コードが実行されたときにのみ存在する必要があります。次に、4つのステートメントをすべてコンパイルして順番に実行し、最後のステートメントが実行されるまでに、load-op
sがパッケージを作成します。
それで、ここで何が起こっているかについてもう少し情報があります:
- 書き込み
'#:some-name
とは、パッケージの一部ではないシンボルを指します。そのため、(1)パッケージが存在すると想定したり、(2)他のパッケージをその名前でいじったりすることなく、シンボリック名を参照できます。
- 次に
'(symbol-name #:some-name)
、シンボルの名前を文字列として抽出します。書いてみません"some-name"
か?あなたはそうすることができました、そしてそれは通常うまくいくでしょう。しかし、この方法は、「モダンモード」の大文字と小文字を区別するLispを実行する場合にはもう少し堅牢です。
find-package
文字列名をLispのパッケージ表現にマップします。この行を実行するまでに、パッケージが存在することを忘れないでください。
intern
指定されたパッケージに含まれる指定された名前のシンボルを返します。
symbol-function
シンボルに関連付けられた関数オブジェクト(ラムダ抽象化、またはより可能性が高いのはそのコンパイル済み表現)を返します。
- そして、
funcall
その関数を呼び出します。ちょっと不格好ですが、残念ながら、コードをロードする呼び出しを組み合わせて、同じファイル内のそのパッケージに存在する名前を持つパッケージを作成するためのより良い方法はありません。