はじめに
Nashorn は日常のスクリプティングにも力を発揮します。Nashorn でシェルスクリプトを書く実例が紹介されていましたので、翻訳してみました。ご覧下さい。
おことわり
以下は jlaskey による Nashorn Blog への投稿の翻訳です。原文はhttps://blogs.oracle.com/nashorn/entry/csi_nashorn_shell_scripting_inでご覧頂けます。翻訳文の URL はhttps://blogs.oracle.com/nashorn_ja/entry/csi_nashorn_shell_scripting_inです。
訳文
The Register の『Gnome プロジェクトが唯一のアプリ開発言語に JavaScript を採用』と題された記事を読んでいた時、Nashorn を使ったシェルスクリプティングについて、まだお話をしていない事を思い出しました。
これは JavaScript のユーザにとってもシェルスクリプトのユーザにとっても守備範囲から外れる話かもしれませんが、一考の価値があります。ウェブブラウザ上の JavaScript にとって利便性の高い機能は、シェルスクリプトでも同じように良い機能です。その上、Nashorn は Java のライブラリや JavaFX にもアクセスできます(プログラムに視覚的な効果を追加する事も可能です)。
Nashorn には -scripting オプションが用意されており、JavaScript を拡張して、シェルスクリプトを書き易くする機能を追加する事が出来ます(ファイルの先頭行が #! で始まるスクリプトファイルも作成出来ます)。-scripting オプションを付けた場合に有効になる機能は以下の通りです。
- $EXEC("コマンド名引数", "入力文字列") 関数で OS のコマンドを別プロセスとして実行
- 標準入力の引き渡し
- 標準出力 ($OUT)
- 標準エラー($ERR)
- 終了コード ($EXIT)
- `コマンド名引数` 形式でのコマンド実行文字列の簡易指定
- ダブルクォートで括った文字列とコマンド実行文字列は置換可能で、シングルクォートで括った文字列は置換不可
- ヒアストリングによる複数行文字列(<<TAG...TAG 形式のヒアストリングは最後に改行が入り、<<<TAG...TAG 形式のヒアストリングは最後の改行が入りません)
- 環境変数へのアクセス ($ENV)
- コマンドライン引数へのアクセス ($ARG)
- exit(code) と quit() によるスクリプトの終了
- # によるコメント
今後もスクリプト作成の実例をたくさんご用意する予定ですが、今回の記事では手始めとしてスクリプトを一つご紹介します。
ソースコードを書いたプログラマの調査
私たちが Nashorn の開発を行っている中で、意図が掴めないコードに突き当たり、そのコードを書いたプログラマを探し出して話をしたいと思うことがよくあります。blaming (問責)と呼ばれる事もありますが、なるべく苦労することなしにコードを理解するには、書いた人に聞くのが一番です。Nashorn は openjdk.java.net にある Mercurial のリポジトリで管理されています。Mercurial もソースコードの変更毎の注釈を保存する機能を持っていますが、ソースコードの特定の場所を直接指定して調査できると便利です。
次のシェルスクリプト(suspect スクリプト)は、ソースコードのファイル名と調べたい箇所の行番号を与えると、ソースコードの変更履歴からその行に関連する情報を抜き出して表示します。
#!/usr/bin/jjs
# このスクリプトはソースコードのファイル名と行番号からソースコードの
# 変更情報を見つけ出します
#
// コマンドの使用方法を表示
function usage() {
error(<<EOS);
usage: suspect javaFileName lineNumber
javaFileName - name of file in local mercurial repository
lineNumber - file line number
EOS
}
// 標準エラー出力にメッセージを出力
function error(message) {
java.lang.System.err.print(message);
exit(1);
}
// コマンドの引数にわかりやすい名前を与える
var fileName = $ARG[0];
var lineNumber = $ARG[1];
// 引数が足りない場合は、コマンドの使用方法を表示
if (!fileName || !lineNumber) {
usage();
}
// ファイル名に .java が欠けていた場合は補完
if (!fileName.endsWith(".java")) {
fileName += ".java";
}
// 引数で与えたファイル名にマッチするファイルを探し、
// 見つかったパス名を配列に格納
var where = `find . -name ${fileName}`.trim().split("\n");
// ファイルがみつからなかった場合
if (where == "") {
error("File ${fileName} is not in the current repository.\n");
} else if (where.length != 1) {
error("File ${fileName} found in multiple locations\n${where.join('\n')}\n");
}
// ファイルの注釈情報を変更履歴番号付きで取得
var annotated = `hg annotate -c ${where}`.split("\n");
// 引数で指定した行番号の行を抜き出す
var line = annotated[lineNumber];
// 行が存在している事を確認
if (!line) {
error("File ${fileName} does not contain line number ${lineNumber}\n");
}
// 履歴番号を抜き出す
var revision = line.substring(0, 12);
// 履歴番号から履歴情報を取り出して表示
print(`hg log -r ${revision}`);
もし SpillProperty.java ファイルの 63 行目の履歴情報を調べたくなったら、suspect スクリプトを以下の様に実行して下さい。
>> suspect SpillProperty 63
changeset: 2:da1e581c933b
user: jlaskey
date: Fri Dec 21 16:36:24 2012 -0400
summary: 8005403: Open-source Nashorn
今回はまだほんの手始めです。今後の更新にもご期待下さい。