2005年12月06日

秘技? 再帰呼出し

お待たせしました。やっと再帰呼び出しです (^^;

前回、チョッと出てきた無限再帰呼出し・・・、試してみた人います? 「黒画面」 が一気に何枚も起動して壮観?ですよね。止めることも出来ずに、ただ Windows がお手上げするのを待つだけですしね。その後 ウィンドウを消すのがまた面倒くさい (^^; そういうときにはタスクマネージャーを起動して、アプリケーションタブから一気に選択して 「タスクの終了」 をすると、チョッとは楽ですよ。

通常は ウィンドウを開く再帰呼出しなんてしませんけどね。でも、ヤバそうだってことは実感出来たと思います。 ・・・なんて、試した人ばっかりのように書いてますが、止めておいたほうがいいですよ (^^;

今回は再帰呼出しで、全てのホルダとファイルにアクセスしてみます。

エクスプローラを開けば判るように、ホルダの中にサブホルダがあり、そのサブホルダの中にもまたサブホルダがあり・・・・・・

ホルダの深さには制限がありません(フルパスで256文字を超えるとアクセスできなくなりますが・・・)。すべてのホルダとファイルにアクセスしようとしたときに、for文 などの普通のループだと、その深さに応じて入れ子状にしなければなりませんので、実装が困難になってしまいます。

何層にも渡って、全く別の構造が繰り返されていては、もう力技しかないかもしれませんが、ホルダのように各層で同じ構造が繰り返されている場合が多いはずです。この構造にだけ注目すれば、面白いことに気付けるハズです。

その構造のある層を処理するルーチンを考えてみましょう。

呼び出されたとき、その層で必要な処理を行い、その中に同じ構造のものがあれば、それの処理を行うルーチンを呼び出してあげればいいですよね。じゃぁ、その処理を行うルーチンって?

そう、自分自身のルーチンですよね。

えぇ〜〜っ? そんなこと出来るの〜??

はい (^^ 局所的な変数を全く扱えない場合には困難なこともありますが、幸い、コマンドプロンプトでは関数やサブルーチンっていった概念が無いようなものですから・・・

あれっ? 何か矛盾してるような・・・

まあ、この場合、外部のプロセスとしてバッチファイルを呼び出せば、そのプロセスの中だけで変数が有効になるので、終了して戻ってきたときには元の値を保持していてくれるんですね。

こちらがサンプルソースです。

  main.bat.txt
  recur.bat.txt

実行ファイルで危険なため、例によって txt 拡張子を付加しています。試す場合は各自のパソコンに保存し、コレを削除してくださいね。

recur.batloop 部はインデントを作成しているだけです。ここは遅延展開を使えば for ループでも対応できるところですね。

main.bat が名前の通りメインになります。これに対象になるホルダ名を引数として起動します。第1引数にホルダ名だけなので、ホルダをドロップしてもOKですよ。第1引数がホルダの場合、recur.bat を第1引数にそのホルダ名、第2引数に階層の深さ、第3引数に出力ファイル名を指定して起動しています。

recur.bat では、階層の深さに従ってインデントを作成し、ホルダ内のファイル名をインデントを付けて全て出力し、その後にサブホルダがあった場合、そのサブホルダ名を出力してから、第1引数にそのホルダ名、第2引数に受け取った階層の深さに1を加えた値、第3引数に受け取った出力ファイル名を指定して起動しています。

実在のホルダの深さは有限ですので、サブホルダが存在しなくなった時点で再帰呼び出しが行われなくなり、無限再帰呼び出しに陥らないようになっています。必ずこのような条件付き脱出口が必要になりますので気を付けて実装するようにしましょうね。

きっと誰もが使ったことがある、ファイルやホルダの検索、あれはなかなか重宝しますよね。あそこまで便利ではありませんが、似たような機能がたったのコレだけのテキストを書くだけで実現できるんですから便利ですよね。

しかも、やらせたい処理内容はあなたの思うまま! (´〜`ニタ〜

オイオイ、何か表現に問題ないか・・・?

応援ポチ  お願いしま〜す。

posted by Woody at 01:42 | 静岡 ☀ | Comment(0) | TrackBack(0) | コマンドプロンプト
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのTrackBack URL
http://blog.seesaa.jp/tb/10264270
※特に許可した場合を除き、一方的な TrackBack は
  SPAM として削除いたします。ご了承ください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。