For Development HEAD DRAFTSearch (procedure/syntax/module):

4.11 インクルード

Special Form: include filename …
Special Form: include-ci filename …

[R7RS base] filename …で指定されるファイルをコンパイル時に読み、 その内容がbeginで囲まれてインクルードフォームの位置に替わりに 置かれているかのように解釈します。 includeフォームはファイルの内容をそのまま読みますが、 include-ciフォームは、あたかもファイル先頭に#!fold-caseが 指定されたかのように、シンボルの大文字小文字を区別しないモードで読みます (大文字小文字の区別参照)。

読み込まれるファイルに文字エンコーディングを指定するコメントがあればそれは そのファイルを読んでいる間有効になります(マルチバイトスクリプト参照)。

filenameが絶対パスならば、そのパスに正確に合致するファイルが探されます。 相対パスなら、まずincludeフォームが 置かれていたファイルからの相対で探され、見つからなければ *load-path*にあるディレクトリからの相対パスが順に試されます。

例: ファイルa.scmには次のコードが書かれているとします。

(define x 0)
(define y 1)

このファイルを別ソースファイルからインクルードすることができます:

(define (foo)
  (include "a.scm")
  (list x y))

この場合、元のソースファイルはあたかも次のように書かれていたかのように解釈されます。

(define (foo)
  (begin
   (define x 0)
   (define y 1))
  (list x y))

(註: バージョン0.9.4では、includeは渡されたパス名が ./../で始まっていた場合は特別な動作をしていました。 コンパイラのカレントディレクトリからの相対でファイルを探していたのです。 これは意図した動作というより、loadとファイル探索ルーチンを共有していた ために生じた仕様でした。しかしloadが常に実行時の動作であるのに対し、 includeでカレントディレクトリからの相対パスを考える意味はほとんどありません。 そこで0.9.5では仕様を変更しました。)

Gaucheには、他のファイルからソースを読んでくる方法がいくつかあります。 以下にインクルードとの比較を説明します。

require (useextendも内部でrequireを呼んでいます)
  • requireincludeもコンパイル時に解釈されます。
  • requireはトップレベルでのみ動作します。 それに対し、includeはどこにでも置けます。
  • requireは ファイルを一度だけ読みます(つまり、2度め以降の同じファイルに対するrequireは 単なる無動作(no-op)になります)。これに対し、includeは現れる場所ごとに ファイルを読み込みます。
  • ファイルは*load-path*から探され、requireフォームが 使われたファイルの位置は関係ありません (但し、add-load-path:relativeフラグを使うことで、 requireフォームを使っているファイルの位置をロードパスに加えることはできます。)
  • requireされたファイル中でカレントモジュールが select-moduleで変更されたとしても、その有効範囲はそのファイル内に留まります。 一方includeは、includeフォームが出現した場所にS式が 挿入されたように解釈されるので、select-moduleの効果は それが挿入された箇所からincludeしているファイルの最後までということになります。 (文字エンコーディング指定コメントおよび、#!fold-case/#!no-fold-case による大文字小文字指定はリーダによって処理されるので、 効果はincludeされるファイルの中に留まります。)
  • requireからロードするファイルが、モジュールを指定せずにトップレベル 束縛を挿入することは禁じられています。別の言い方をすれば、 requireするファイルは一般的にdefine-moduleselect-module、 あるいはdefine-libraryを使う必要があるということです。 詳しい議論はrequireとprovideを参照してください。 一方で、includeにはそういった制限はありません。
load
  • includeがコンパイル時に解釈されるのに対し、こちらは実行時に解釈されます。
  • トップレベルでのみ動作します。それに対し、includeはどこにでも置けます。
  • ファイルは*load-path*から探されます。 但しファイルが./../で始まっていた場合は、 まずカレントディレクトリ相対で探され、それから*load-path*が探されます。
  • requireと同様、ロードされるファイル中でカレントモジュールを変えても、 その効果はload終了時までです。

通常、他のファイルに書かれたソースファイルを取り込むのに適した方法は require (もしくはuseextend) です。 includeフォームは、requireでは実現が難しいトリックのために使います。 例えば、第三者がR5RS向けに書いたコードを、Gaucheのモジュールシステムでラップしたい場合、 includeを使う 次のような内容の小さなファイルをそのコードのファイルと同じディレクトリに置いておけば、 第三者のコードを一切変えることなく、(use third-party-module) で コードをロードできます。

(define-module third-party-module
  (export proc ...)
  (include "third-party-source.scm"))


For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT