ファイルをバイトコンパイルすると、コンパイラが認識していない関数に関する警告が表示されることがよくあります(コンパイラエラーを参照)。これが実際の問題を示している場合もありますが、通常、該当する関数は別のファイルで定義されており、そのコードが実行される際にそのファイルが読み込まれます。例えば、simple.elをバイトコンパイルすると、以前は次のような警告が表示されていました:
simple.el:8727:1:Warning: the function `shell-mode' is not known to be
defined.
実際、shell-mode は shell-mode を呼び出す前に (require
'shell) を実行する関数内でのみ使用されるため、shell-mode
は実行時に適切に定義されます。このような警告が実際の問題を示していないと分かっている場合は、その警告を抑制しておくのが得策です。そうすることで、実際の問題である可能性のある新たな警告がより目立つようになります。declare-function ではそれを実現しています。
該当する関数を初めて使用する前に、declare-function
ステートメントを追加するだけで済みます:
(declare-function shell-mode "shell" ())
これは、shell-mode が shell.el で定義されていることを示しています(‘.el’
は省略可能です)。コンパイラは、そのファイルが実際に関数を定義していることを前提としており、チェックは行いません。
省略可能な第3引数は、shell-mode
の引数リストを指定します。この場合、引数は取りません(nil
は、値を指定しないこととは異なります)。それ以外のケースでは、(file &optional
overwrite)
のようになる場合があります。引数リストを指定する必要はありませんが、指定すればバイトコンパイラが呼び出しが宣言と一致しているかを確認できます。
バイトコンパイラに対し、function がファイル file で定義されているものとして扱うよう指示します。省略可能な第3引数 arglist は、引数リストが未指定であることを意味する t
か、あるいは defun と同じ形式(括弧を含む)の仮引数リストのいずれかです。省略された arglist は、nil ではなくデフォルトで t となります。これは省略引数としては異例の挙動であり、第4引数は指定するが第3引数は指定しない場合は、通常の
nil ではなく、第3引数のプレースホルダーとして t を指定しなければならないことを意味します。省略可能な第4引数 fileonly が non-nil である場合は、file が存在することのみを確認し、それが実際に function
を定義していることまでは確認しません。
これらの関数が実際に declare-function
で指定された箇所で宣言されているかを確認するには、check-declare-file
を使用して1つのソースファイル内のすべての declare-function
呼び出しをチェックするか、check-declare-directory
を使用して特定のディレクトリおよびその配下にあるすべてのファイルをチェックしてください。これらのコマンドが問題のある宣言を検出した場合、検出された各問題を記述した
*Warnings* バッファが表示されます。警告の報告 を参照してください。
これらのコマンドは、locate-library
を用いて関数の定義が含まれているはずのファイルを探します。該当するファイルが見つからない場合は、declare-function
の呼び出しを含むファイルのディレクトリを基準として、定義ファイル名を展開します。
また、ファイル名の末尾に ‘.c’ または ‘.m’ を指定することで、その関数がプリミティブであると指定することもできます。これは、特定のシステムでのみ定義されているプリミティブを呼び出す場合にのみ有用です。ほとんどのプリミティブは常に定義されているため、警告が表示されることはありません。
ファイルによっては、外部パッケージの関数をオプションで使用することがありますが、それらのコマンドが検索する場所では見つからない場合があります。declare-function ステートメントのファイル名の先頭に文字列 ‘ext:’ を付加すると、ファイルが見つかった場合にその関数定義(または fileonly が nil
でない場合は単なる存在確認)がチェックされ、見つからなかった場合はエラーなくファイルがスキップされます。ただし、変数 check-declare-ext-errors を nil
以外の値にカスタマイズした場合、これらのコマンドはそのような欠落ファイルに対して ‘file not
found’ 警告を出力します。
‘check-declare’
が認識しない関数定義がいくつかあります(例:defstruct
やその他のいくつかのマクロ)。このような場合、declare-function に nil fileonly
以外の引数を渡すことで、ファイルが存在することのみを確認し、実際に関数が定義されているかどうかはチェックしないようにできます。なお、引数リストを指定せずにこれを行うには、arglist 引数を t に設定する必要があります(nil は、未指定の引数リストではなく、空の引数リストを意味するためです)。