JScript(WSH)でワンライナー

id:eel3:20120227:1330277669 を元に、今度はWSHJScriptワンライナーする為の仕組みを作ってみた。

/*jslint windows: true, evil: true, maxerr: 50, indent: 2 */
(function () {
  'use strict';
  if (WScript.Arguments.length !== 1) {
    WScript.StdErr.WriteLine('usage: cscript ' + WScript.ScriptName + ' "evaluate script"');
    WScript.Quit(1);
  }

  try {
    eval(WScript.Arguments(0));
  } catch (e) {
    if (e instanceof Error) {
      WScript.StdErr.WriteLine(e.name + ": " + e.message);
    } else {
      WScript.StdErr.WriteLine("Error " + e.number + ": " + e.description);
    }
    WScript.Quit(2);
  }
  WScript.Quit(0);
}());

今度も思いっきり eval を使っているので危なっかしい。あと例外の捕捉回りのコードは、WSHの例外がErrorクラス(ないしその派生)を継承しているのなら正しくない。

WScript.Argumentsの仕様による制限でダブルクォートを含む文字列を引数としてうまく渡すことができないので、文字列リテラルにはシングルクォートを使う必要がある。

D:\temp>cscript jscript_oneliner.js //Nologo "WScript.Echo('hello, world')"
hello, world

D:\temp>cscript jscript_oneliner.js //Nologo "for (i in [0, 0, 0]) WScript.Echo(i)"
0
1
2

D:\temp>cscript jscript_oneliner.js //Nologo "for (s in { foo: 0, bar: 0, baz: 0 }) WScript.Echo(s)"
foo
bar
baz

D:\temp>

Windows XP上のWSH 5.7で動かしている為か、ワンライナーのコードに「'use strict'」は適用されない模様。

これまたバッチファイルでラッピング。

@echo off
cscript.exe "%~dp0jscript_oneliner.js" //Nologo %*
D:\temp>jscriptol.bat "WScript.Echo('hello, world')"
hello, world

D:\temp>

PhantomJS版よりも需要は無いだろうなあ。