2016-05-20 2 views
3

module->language-infomodule->importsmodule->exportsのようなラケットの関数は、そのモジュールが宣言されているが、必ずしも訪問またはインスタンス化されるとは限りません。モジュールの訪問、インスタンス化、および宣言の違いは何ですか?

今、dynamic-requireには、訪問とインスタンス化の両方を含むモジュールの必要な方法に関するいくつかのオプションがあるようです。

私は、モジュールの宣言、モジュールの訪問、モジュールのインスタンス化の違いは何ですか?

答えて

3

モジュールの宣言は、このモジュールが現在の名前空間のどこかにあることだけです。これは、requireによって、またはコードに文字通りモジュールを書き出すことの両方によって行うことができます。

モジュールは、訪問およびインスタンスは、もう少しトリッキー理解することで、最高のように記述することができる。

  1. モジュールは、位相レベル1(マクロ/コンパイルタイムコード)を実行している訪問し、そして相を実行していませんレベル0(ランタイムコード)。

  2. モジュールインスタンシエーションは位相レベル0のコードを実行していますが、位相レベル1のコードは実行していません。それがコンパイルされていない場合

さて、トリッキーなビットは、位相レベル0のコードを実行するために、あなたが持っている必要があり、以前より高いレベルのすべてを実行するには、コードを段階的。しかし、このモジュールがすでに訪問されて(コンパイルされている場合)、フェーズレベル1のコードは再び実行されません。

これは、以下のモジュールで見ることができるが、test.rktと呼ば:

#lang racket 

(require (for-meta 2 racket/base)) 
(displayln "phase 0") 
(begin-for-syntax 
    (displayln "phase 1") 
    (begin-for-syntax 
    (displayln "phase 2"))) 

このモジュールは、位相0で実行されるコード、フェーズ1およびフェーズ2(マクロ展開フェーズのマクロ展開)を有しています。これらの各フェーズでは、フェーズが実行されていることを示す行が出力されます。このモジュールを使用すると、モジュールがインスタンス化された時刻がわかります。私たちはDrRacketでこれを実行すると、出力のようなものになります

#lang racket 
(dynamic-require "test.rkt" #f) 

さて、test.rktをインスタンス化し、次のファイルを作成してみましょう今

phase 2 
phase 1 
phase 0 

を、私たちはのでphase 0を見ますモジュールがインスタンス化されています。しかしこの場合、phase 2phase 1も表示されます。これは、モジュールの構文フェーズがphase 0コードを実行するために必ずインスタンス化されたためです。あなたは再びそれを実行する場合は

、あなたが取得します(電源がオンになって、すでにコンパイルされたファイルのキャッシュを持っていると仮定した場合):この場合

phase 0 

phase 1と高いコードがすでに持っているので、あなただけphase 0を見ます拡張されました。同様の結果を得るためには、動的には0が必要です。今

、代わりにdynamic-require0または#fに渡すので、私たちは私たちに次のファイルを与える、(void)に渡された場合:

#lang racket 
(dynamic-require "test.rkt" (void)) 

を次に出力はあなたがキャッシングをオンにコンパイルしていると仮定すると、再び(になります

phase 1 

これは、実行時(フェーズ0)コードではなく、マクロレベル(フェーズ1)コードがここで実行されているためです。我々はtest.rktにわずかな変更を加えると、(キャッシュを無効にするために)再びそれを保存すると、我々はなりますが:

phase 2 
phase 1 

をラケットはphase 1コードを実行できるようにするために、phase 2コードを展開していたためです。コンパイルされたモジュールのキャッシュが更新されていることをあなたは再びそれを実行した場合さて、それは出力のみの意志:

最後に
phase 1 

、そこではありません(私が間違っている場合私の知る限り、これを更新してください) dynamic-requireを直接使用してフェーズレベル1より高いコードが実行されることを保証する方法はありません。

関連する問題