2011年4月17日日曜日

昔懐かしいコマンドプロンプトでのカウント

GUIが無かった時代の、コマンドプロンプト上でのカウント表示のコードです。 プログレスバーがまだ無かったときはこんなことをしていました。 Rhinoで遊んでいるときにコマンドプロンプトを使っているので、思い出して書いてみました。

var out = java.lang.System.out;
print_test(0);

function print_test(i)
{
    if(100 < i)
    {
        out.println(' end.');
        return;
    }
    
    out.format('\rtest %2d%%', java.lang.Integer(i) );
    
    java.lang.Thread.sleep(100);
    
    print_test(i + 1);
}

実行すると「test ?%」と表示されます。 ?の部分が1から100までカウントアップされ、100%になると「test 100% end.」と表示され終わります。

out.formatで最初にキャリッジリターン(\r)を出力しているのがポイントです。 \nは改行して行頭に、\rは改行せずに行頭に移動します。 \rして新しい文字列(test ?%)で書き直せば、見た目は ?% の部分だけが更新されているように見えます。

\rってOSによって違うんでしたっけ? 古いマッキントッシュだけ改行に\rを使う...のか? 古いマッキントッシュを持ってないので確認しようが無いですけど。

まぁ、気を取り直して、Rhinoに標準でついているprintは改行してしまうのでこういうコードには使えません。 代わりにjavaのSystem.outを使います。 \rで行頭に移動しても、前にout.formatした文字は残っています。 新しい文字列で上書きして更新です。 書き直す文字列が短いときは多めにスペースをはいて、上書きして前の文字を消します。

う~ん、あらためて、今さら書くようなコードじゃないですよね? でもまぁ、Rhinoはコマンドプロンプト上で動かすので使う機会があるかも? RhinoでGUIとか、さすがにやる人は居ない...とも言えないのか。 普通に「ちょっとしたコードをjavascriptで書けるのって気楽でいいなぁ」って人は試してみてください。

本題はこんな感じで。 あと、瑣末な雑文が4つ。

色んなプログラムの入門書で「\nは紹介されているけど\rは出てこない」ってのは何なんでしょうかね? それで\rは絶滅危惧種っぽくなっている気がします。 使っている人は普通に使ってるんだろうけど。

java.lang.Integer(i)を使っているのはjavascriptの変数が内部でdouble型として扱われている(らしい)からです。 こうしないとout.formatの %2d で「整数じゃない」と怒られます。

無駄に再帰の形になっているのはjavascriptのsetTimeoutを試した跡です。 Rhinoでは使えなくてThread.sleepに変更しました。

Rhinoは例外を出す可能性があるコードをtry~catchで囲む必要がないですよね。 1回使うだけのスクリプトを書くときとかは楽でいいです。 そこそこ大きいコードを書くときはお行儀よくしなきゃダメでしょうけど。