今回は、「進捗表示と上書き確認機能を備えたファイルコピーツール」で紹介したスクリプトで使用している「コピーの進捗報告を受け取るコールバック関数」に書かれている#forcerefの行の意味について詳しく解説します。
【AutoIt】進捗表示と上書き確認機能を備えたファイルコピーツール
「#forceref」の意味は?詳しい解説
この#forcerefという行は、AutoIt のスクリプトチェッカー(Au3Check)に対して「この変数はコードの中で使っていませんが、意図的なものなので警告を出さないでください」と伝えるための、おまじないのような命令です。
「未使用の変数」という警告
プログラムを書いていると、うっかりミスで「変数を準備したのに、一度も使わなかった」ということがよくあります。
これはバグの原因になる可能性があるため、多くのプログラミング言語では、コードをチェックする際に「この変数は使われていませんよ」という警告を出してくれます。
なぜこのコードで必要か
今回の_ProgressProc関数は、Windows API から呼び出してもらうために作成しています。
Windows API との間には、「この関数を呼び出すときは、必ずこれだけの引数($iTotalFileSize, $iTotalBytesTransferredなど)をこの順番で渡します」という厳格なルール(仕様)があります。そのため、_ProgressProc関数は、たとえ使わなくても、そのルール通りに全ての引数を受け取る準備をしておく必要があります。
今回のスクリプトでは、進捗を計算するために$iTotalFileSizeと$iTotalBytesTransferredの2つしか使っていません。残りの6つの変数は、ルール上受け取っているだけで、中身は使っていません。
もし#forcerefがないと、スクリプトチェッカーは「$iStreamSizeや$pDataなどの変数が使われていません!」という警告を大量に出してしまいます。
例えるなら
これは、例えば「会議には必ず 8人全員で出席してください」というルールのある会議に出席するようなものです。
- 発言する(コードで使う)のは、そのうちの 2人だけ。
- 残りの 6人(使わない変数)は、ルール上そこに座っているだけで、一言も発しません。
#forcerefは、「この 6人はルール上必須なので、発言しなくても問題ありません」と、議事録係(スクリプトチェッカー)に事前に伝えておくメモ書きのようなものです。
#forcerefは、コールバック関数のように、関数の引数の形が外部の仕様によって厳密に決められており、意図的に使わない引数が存在する場合に、不要な警告を抑制してコードを綺麗に保つための、AutoIt 開発者向けの便利な機能です。
#forceref の行をコメントアウトしても何も変わらないのはなぜ?
#forcerefが機能しないのは、#AutoIt3Wrapper_AU3Check_Parametersという、AutoIt3Wrapperだけが理解できる特殊な命令(ディレクティブ)を追加していないためです。
スクリプトの一番最初の行に、以下の 1行を追加すると、
#AutoIt3Wrapper_AU3Check_Parameters=-d -q -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
「これからこのスクリプトをチェックする際は、Au3Check.exeを以下のパラメータ付きで実行してください」という意味になります。
| スイッチ | 意味 |
|---|---|
| -q | エラー/警告のみ出力する |
| -d | 変数の宣言を必須にする (Opt("MustDeclareVars", 1)) |
| -w 1 | 既にインクルードされているファイルに関する警告 |
| -w 2 | #comments-end がない場合の警告 |
| -w 3 | 既に宣言されている変数に関する警告 |
| -w 4 | グローバルスコープでローカル変数が使われた場合の警告 |
| -w 5 | 宣言されているが使用されていない変数に関する警告 |
| -w 6 | Dim を使用した場合の警告 |
| -w 7 | ByRef パラメータに Constなどを渡した場合の警告 |
これらのパラメータは、「グローバルスコープ」または「ローカルスコープ」で作用します。
次のスクリプトをご覧ください。パラメータ「-w 5」を指定しています。
実際にこのスクリプトで文法のチェック(Ctrl + F5)を行ってみてください。関数の中に#forcerefの行を追加しているので、警告は表示されません。
#AutoIt3Wrapper_AU3Check_Parameters=-w 5
#include <MsgBoxConstants.au3>
; --- メイン処理 ---
; 幅10、高さ5の面積を計算する
$iResult = _CalculateArea(10, 5, "Rectangle", "cm")
MsgBox($MB_OK, "計算結果", "面積は " & $iResult & " です。")
; --- 関数定義 ---
Func _CalculateArea($iWidth, $iHeight, $sShapeName, $sUnit)
; この行を削除してテストします
#forceref $sShapeName, $sUnit
; 実際の計算では、$iWidth と $iHeight しか使いません
Local $iArea = $iWidth * $iHeight
Return $iArea
EndFunc ;==>_CalculateArea
しかし、#forcerefの行をコメントアウトした場合、「warning: $sUnit: declared, but not used in func.(警告: $sUnit: 宣言されていますが、func では使用されていません。)」という警告が表示されます。
#AutoIt3Wrapper_AU3Check_Parametersは、普段は使わないけれど、特定のスクリプトだけで特別なチェックをしたい、という場面で非常に役立ちます。
ファイル単位で柔軟にコードチェックのルールをカスタマイズするための、開発者向けの便利な機能です。 チームで開発する際に、全員のチェックルールを一時的に揃えたい場合などにも役立ちます。
コメント