Next: , Previous: , Up: Loading   [Contents][Index]


15.7 名前つき機能

providerequireは、autoloadにかわってファイルを自動的にロードする関数です。これらは名前付きのフィーチャ(feature: 機能)という面で機能します。オートロードは特定の関数の呼び出しをトリガーにしますが、フィーチャは最初は他のプログラムが名前により問い合わせたときにロードされます。

フィーチャ名とは関数や変数などのコレクションを表すシンボルです。これらを定義するファイルは、そのフィーチャをプロバイド(provide: 提供)するべきです。これらのフィーチャを使用する他のプログラムは、その機能をリクワイア(require: 要求)することによって、それらが定義されているか確認できるでしょう。これは定義がまだロードされていなければ、定義ファイルをロードします。

フィーチャをリクワイアするには、フィーチャ名を引数としてrequireを呼び出します。requireは意図する機能がすでにプロバイドされているか確認するために、グローバル変数featuresを調べます。もしプロバイドされていなければ、適切なファイルからそのフィーチャをロードします。このファイルはそのフィーチャをfeaturesに追加するために、トップレベルでprovideを呼び出すべきです。これに失敗するとrequireはエラーをシグナルします。

たとえばidlwave.el内のidlwave-complete-filenameにたいする定義には以下のコードが含まれます:

(defun idlwave-complete-filename ()
  "Use the comint stuff to complete a file name."
   (require 'comint)
   (let* ((comint-file-name-chars "~/A-Za-z0-9+@:_.$#%={}\\-")
          (comint-completion-addsuffix nil)
          ...)
       (comint-dynamic-complete-filename)))

(require 'comint)comint.elがまだロードされていなければ、comint-dynamic-complete-filenameが確実に定義されるようにそのファイルをロードします。フィーチャは通常はそれらを提供するファイルにしたがって命名されるため、requireにファイル名を与える必要はありません(require命令文がletのbodyの外側にあるのが重要なことに注意。変数がletバインドされているライブラリーをロードすることにより、意図せぬ結果、つまりletをexitした後にその変数がアンバインドされる)。

comint.elには以下のトップレベル式が含まれます:

(provide 'comint)

これはcomintをグローバルなリストfeaturesに追加するので、(require 'comint)は今後何も行う必要がないことを知ることができます。

ファイルのトップレベルでrequireが使用されたときは、それをロードしたときと同様、そのファイルをバイトコンパイル(Byte Compilationを参照)するときにも効果が表れます。これはリクワイアされたパッケージがマクロを含んでいて、バイトコンパイラーがそれを知らなければならない場合です。これはrequireによりロードされるファイルで定義される関数と変数にへのバイトコンパイラーの警告も無効にします。

バイトコンパイルの間にトップレベルのrequireが評価されるとしても、provide呼び出しは評価されません。したがって以下の例のようにprovideの後に同じ機能にたいするrequireを含めることにより、バイトコンパイル前に定義しているファイルを確実にロードできます。

(provide 'my-feature)  ; バイトコンパイラーには無視され
                       ;   loadには評価される
(require 'my-feature)  ; バイトコンパイラーにより評価される。

コンパイラーはprovideを無視して、その後に対象のファイルをロードすることによりrequireが処理されます。ファイルのロードはprovide呼び出しを実行するので、後続のrequireはファイルがロードされていれば何も行いません。

Function: provide feature &optional subfeatures

この関数はカレントEmacsセッションにfeatureがロードされたこと、あるいはロードされつつあることをアナウンスする。これはfeatureに関連する機能が他のLispプログラムから利用可能できる、あるいは利用可能になることを意味する。

provideを呼び出すことによる直接的な効果は、まだfeaturefeatures内に存在しない場合はリストの先頭に追加して、それを必要としているeval-after-loadコードを呼び出します(Hooks for Loadingを参照)。引数featureはシンボルでなければなりません。providefeatureをリターンします。

subfeaturesが与えられたら、それはfeatureの当該バージョンによりプロバイドされる特定のサブフィーチャのセットを示すシンボルのリストであること。featurepを使用して、サブフィーチャの存在をテストできる。そのパッケージがロードされるかどうか、あるいは与えられるバージョンで存在するかどうか不明であるようなあるパッケージ(1つのfeature)において、パッケージの種々の部分やパッケージ機能に命名することでそのパッケージを使いやすくするのが困難なほど複雑なときに使用するというのがサブフィーチャのアイデアである。Network Feature Testingの例を参照されたい。

features
     ⇒ (bar bish)

(provide 'foo)
     ⇒ foo
features
     ⇒ (foo bar bish)

オートロードによりあるファイルがロードされて、その内容の評価エラーによりストップしたときは、そのロードの間に発生した関数定義やprovide呼び出しはアンドゥされる。Autoloadを参照のこと。

Function: require feature &optional filename noerror

この関数はカレントEmacsセッションにおいて、featureが存在するかどうかを((featurep feature)を使用する。以下参照)をチェックする。引数featureはシンボルでなければならない。

そのフィーチャが存在しなければ、requireloadによってfilenameをロードする。filenameが与えられなければ、シンボルfeatureの名前がロードするファイル名のベースとして使用される。しかしこの場合、requirefeatureを探すためにサフィックス‘.el’と‘.elc’の追加を強制する(圧縮ファイルのサフィックスに拡張されるかもしれない)。名前がただのfeatureというファイルは使用されない(変数load-suffixesは要求されるLispサフィックスを正確に指定する)。

noerrorが非nilなら、ファイルの実際のロードにおけるエラーを抑止する。この場合はそのファイルのロードが失敗するとrequirenilをリターンする。通常ではrequirefeatureをリターンする。

ファイルのロードは成功したがfeatureをプロバイドしていなければ、requireは‘Required feature feature was not provided’のようにエラーをシグナルする。

Function: featurep feature &optional subfeature

この関数はカレントEmacsセッションでfeatureがプロバイドされていれば(たとえばfeaturefeaturesのメンバーなら)tをリターンする。subfeatureが非nilなら、この関数はサブフィーチャも同様にプロバイドされているとき(たとえばsubfeatureがシンボルfeatureのプロパティsubfeatureのメンバーのとき)だけtをリターンする。

Variable: features

この変数の値はシンボルのリストであり、そのシンボルはカレントEmacsセッションにロードされたフィーチャである。シンボルはそれぞれprovideを呼び出すことにより、このリストにputされたものである。リストfeatures内の要素の順番に意味はない。