m2

JScript でハマる日々

Windows Script Programming でよく使われているイディオムに以下のようなものがあります。

@if(0)==(0) ECHO OFF
CScript.exe //NoLogo //E:JScript "%~f0" %*
GOTO :EOF
@end

WScript.echo("こんにちは")
:


これは本体を .CMD (.BAT) ファイルとして保存しておきながら、実行の際は自分自身を JScript として実行するというものです。
んで、なんでこれがうまく動作するのかがよくわからなかったので調べてました。


まず前半の CScript 実行の部分はなんとなく理解。

  • コマンドの先頭には @ を付けてコマンドエコーを抑止する機能があるので、if にも付けられる。
  • 普通に (0) == (0)は true だから echo off。
  • CScript で自分自身を引数つきで起動し、ファイルの終了位置まで(つまりJScriptが書かれている部分を)読み飛ばす。


問題は JScript として実行する際に @if 〜 @end までを読み飛ばす仕組み。これにハマりました。実はこれ、「@if...@elif...@else...@end ステートメント」と呼ぶものらしいです。

条件式の値を評価し、条件に応じて適切なステートメントを実行します。
@if (
condition1
)
text1

@end

JScript 8.0 @if...@elif...@else...@end ステートメント

んでこのステートメントってのはコンパイルできなくてもぜんぜんオッケーで、条件が合致した時点で初めて評価されるみたい(プリコンパイラディレクティブ?)。
そこで元のコードをもう少し単純化するとこうなります。

@if(0)
    こんにちは
@end
WScript.echo("こんにちは")

なんと! CMD の時点では @if(0)==(0) として true だったものが、JScript では @if(0) となって確かに false となっています。これはすごいですね。


いや、すごいんだけど、なんか、釈然としない、気が、します。