[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
(use
とextend
も内部でrequire
を呼んでいます)require
もinclude
もコンパイル時に解釈されます。
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-module
やselect-module
、
あるいはdefine-library
を使う必要があるということです。
詳しい議論はrequireとprovideを参照してください。
一方で、include
にはそういった制限はありません。
load
include
がコンパイル時に解釈されるのに対し、こちらは実行時に解釈されます。
include
はどこにでも置けます。
*load-path*
から探されます。
但しファイルが./
か../
で始まっていた場合は、
まずカレントディレクトリ相対で探され、それから*load-path*
が探されます。
require
と同様、ロードされるファイル中でカレントモジュールを変えても、
その効果はload
終了時までです。
通常、他のファイルに書かれたソースファイルを取り込むのに適した方法は
require
(もしくはuse
やextend
) です。
include
フォームは、require
では実現が難しいトリックのために使います。
例えば、第三者がR5RS向けに書いたコードを、Gaucheのモジュールシステムでラップしたい場合、
include
を使う
次のような内容の小さなファイルをそのコードのファイルと同じディレクトリに置いておけば、
第三者のコードを一切変えることなく、(use third-party-module)
で
コードをロードできます。
(define-module third-party-module (export proc ...) (include "third-party-source.scm"))