これは、拙作 ecalc.pl 用のドロップレット。バッチファイルなので、Windows ユーザー専用となる。『ドロップレット』とは、ドラッグ & ドロップによる操作で実行できるプログラムのこと。バッチファイル(Windows/DOS) や アップルスクリプト(Mac) のプログラミングを知っていると、ドロップレットを割と簡単に作ることができる。通常、ドロップレットというと Mac の専売特許のように思われがちだが、実際にはバッチの方が簡単にドロップレットを作成できる。
ただし、バッチで出来ることには限界がある。ドロップレットは簡単に作れても、実際にはたいしたことはできないのが現実だ。それを補うため、ecalc.bat では、部分的に Perl コードを記述している。バッチ・テクニックとしては反則ワザだが、それを差し引いても ecalc.bat は、バッチ処理の基本テクが満載のソースなので、きっと初級者の参考になると思う。バッチに興味がある人は、一度ソースを見ておくことを薦める(環境変数には日本語(全角文字)が使える…これは知らない人が多いのでは?)。
このバッチのショートカットアイコンをデスクトップに置いて、計算式を記述したテキストファイルをそのアイコンにドラッグ & ドロップすれば、ecalc.pl を起動し、手軽に入力ファイルの計算ができる。
計算結果は、入力ファイルが入っているフォルダに『入力ファイル名_res.txt』という名前で出力される。例えば、入力ファイル名が『exp.txt』の場合、出力ファイル名は『exp.txt_res.txt』となる。res は『レスポンス(返信)』とか『リザルト(結果)』のスペルを略したものと捉えてほしい。
その出力ファイルは、実行終了時に Windows 版のエディタで直ちに表示される。初期設定では『メモ帳』になっているが、設定を変えることで、ユーザーが日常使っているエディタで表示させることもできる。
ecalc.pl は、ファイルから式を読み込む時、特に威力を発揮するスクリプトだが、一般のパソコンユーザーは『リダイレクト入力』を知らない人が多いので、ecalc.pl が実装しているダイナミックな機能をフル活用できないかも知れない…。そう考えて作ったのが、この ecalc.bat だ。つまり『リダイレクト入力をドラッグ & ドロップで実現するバッチ』だ。
rem [ユーザー設定:]
rem ecalc.pl のフルパスを拡張子付きのフルネームで指定する
if not "個人設定"=="" set ecalcpl=g:\bat\prl\ecalc.pl
rem テキストを閲覧するエディタを指定する。デフォルトはメモ帳(notepad)
if not "個人設定"=="" set 閲覧=notepad
『rem文』に書いてあるとおり、まず ecalc.pl
のフルパスを拡張子付きのフルネームで指定してください。
ここに記述されているのは作者の設定なので、
それをあなたの設定に変えます。例えば、ecalc.pl を『C:\bat\prl』
に入れてある場合は、次のように指定してください。if not "個人設定"=="" set ecalcpl=c:\bat\prl\ecalc.plちなみに、この設定が誤っている場合、ecalc.bat は実行ファイルの検索パスである環境変数『path』 とカレントディレクトリを検索して『ecalc.pl』 があるかどうかを探すようにしてあるので、パスの通ったフォルダに ecalc.pl が置かれている場合は、 ここは指定しなくても実行可能だ。
if not "個人設定"=="" set 閲覧=wzeditorただし、レジストリを全くいじらないエディタを使っている人は、 フルパスで記述してください。例えばフリーソフトの『K2Editor』 を登録するには次のように記述する(作者の場合)。
if not "個人設定"=="" set 閲覧=C:\tools\k2editor\K2Editor.exeエディタは、関連付けされていないテキストでも開けるようにするため、 必ずデスクトップにショートカットを置きましょう。 エディタのフルパスは、デスクトップにショートカットを置いてあるなら、 そのプロパティからペーストできるし。ユーザー設定は以上。 上書き保存して、メモ帳を閉じてください。
デスクトップに移動したアイコンに、計算式を記述したテキストファイルをドラッグすれば、手軽に ecalc.pl を起動して計算することができる。試しに同梱の『exp.txt』をドラッグ & ドロップしてみてください。正常にインストールされていれば、直ちに指定のエディタで計算結果が表示されるはずだ。最初にやることは以上だ。
上記の説明では、デスクトップにショートカットを置く…と書いたが、ecalc.bat 本体をデスクトップに移動して使っても、もちろん構わない。その辺は、ユーザーの好み…ということで。
ecalc.bat のアーカイブには、exp.txt というサンプル・テキストが含まれている。その内容は次のとおりだ。
# ecalc.pl & ecalc.bat を試すためのサンプル・テキスト # 計算式を記述した「入力ファイル」はこんな感じに作成すれば良い。 # ←このように先頭が「#」から始まっている行はコメントとなる(出力する)。 # このファイル『exp.txt』を、ecalc.bat のショートカットにドラッグすると、 # 計算結果を『exp.txt_res.txt』に出力し、メモ帳などのエディタで表示できる。 0+1 1+2 # -nオプション適用(行番号を出力) -n # 行番号は 0: から始まる 2+3 3*4 4/2 5-3 # メモリー計算の例 # 円周(2πr) # 円の面積(πr**2) # r==5 とすると… 3.1415926535 2 * 6: * 5 6: * 5** 2 # -r オプション適用(答だけ出力) -r 9 / 0 10 ** 10 # -r オプション解除 -cr # 16進数を10進数に変換 0xff # 8進数を10進数に変換 0755 # 以降は全てコメント(出力しない) 00 ecalc.pl は、ファイルから式を読み込む場合、eof に達した時点で実行を終了 するようにしてあるが、元々は 00 を入力すると実行を終了する仕様なので、そ れを逆手にとってワザと 00 を記述することで 00 以降にコメントを記述するこ とができる。 ただし、00 の行を読み込んだ時点で ecalc.pl は実行を終了するため、その行 以降を標準出力することはできない。
このテキストをショートカット・アイコンにドラッグすると、直ちに計算し、その結果をエディタで表示する。動作については、実際に試して体感してもらいたい。計算結果は、exp.txt_res.txt に出力される。出力ファイルの内容は次のとおりだ。
# ecalc.pl & ecalc.bat を試すためのサンプル・テキスト # 計算式を記述した「入力ファイル」はこんな感じに作成すれば良い。 # ←このように先頭が「#」から始まっている行はコメントとなる(出力する)。 # このファイル『exp.txt』を、ecalc.bat のショートカットにドラッグすると、 # 計算結果を『exp.txt_res.txt』に出力し、メモ帳などのエディタで表示できる。 0+1 = 1 1+2 = 3 # -nオプション適用(行番号を出力) # 行番号は 0: から始まる 2: 2+3 = 5 3: 3*4 = 12 4: 4/2 = 2 5: 5-3 = 2 # メモリー計算の例 # 円周(2πr) # 円の面積(πr**2) # r==5 とすると… 6: 3.1415926535 = 3.1415926535 7: 2 * 6: * 5 = 2 * 3.1415926535 * 5 = 31.415926535 8: 6: * 5** 2 = 3.1415926535 * 5** 2 = 78.5398163375 # -r オプション適用(答だけ出力) 9: 0 # >>> Illegal division by zero at (eval 33) line 1, <STDIN> line 32. 10: 10000000000 # -r オプション解除 # 16進数を10進数に変換 11: 0xff = 255 # 8進数を10進数に変換 12: 0755 = 493 # 以降は全てコメント(出力しない) # error! 9: >>> Illegal division by zero at (eval 33) line 1, <STDIN> line 32.
この例では、9: 行目で『ディビジョン・バイ・ゼロ』エラーが発生している。エラーが発生すると、最終行にエラーメッセージが出力される。何となく、使い方が分かったかな? あとは、実際に使って体感してください。
ecalc.bat は、拡張子が『.tem』になっている入力ファイルを読み込むと、計算はせず、複製を作ってエディタで開くだけとする。要するに .tem を雛形ファイル(テンプレート)と断定する。複製ファイルの名前は…
『〜〜.tem』 → 『〜〜_2010_03_04.txt』
…のように今日の年月日が付加されて命名される。この機能を実現するため、部分的に Perl を使っている。当初、.tmp .temp を雛形ファイル名にするつもりだったが、一時ファイル(テンポラリファイル)と勘違いされて削除される可能性があるため .tem にした。
ecalc.bat のアーカイブには、kakutei_A_h21.tem, kakutei_B_h21.tem というサンプル・テキストが含まれている。これらは、それぞれ ecalc.pl を使っての確定申告 A用、B用の計算シートになっている。この計算シートは『平成21年分 所得税の確定申告の手引き』を参考資料として作成した(確定申告書 A用、B用があり、確定申告の期間中に税務署に行けば貰える)。『平成21年分』なので、次回の申告(平成22年分)でそのまま使える保障はないが、おそらくはちょっと修正するだけで済むと思う。どうなるかは、現政権の舵取り次第…。菅内閣のお手並み拝見といこう。
試しに kakutei_A_h21.tem を ecalc.bat(またはそのアイコン)にドラッグすると…
(ダブルクリックしても駄目だよ。分かっていると思うが、念のため)
kakutei_A_h21_2010_03_04.txt
…という複製ファイルが作成され、それがエディタで表示される。そのファイルに必要事項を入力すれば良い。完成したら、保存してファイルを閉じ、改めてそれを ecalc.bat のアイコンにドラッグしてやれば、所得金額、税金額が自動算出される仕組みだ。
ecalc.bat はバッチファイルなので、残念ながら Windows 限定のプログラムとなる。ならば、これを Perl スクリプトで全面的に書き直せば、Linux でも動作するドロップレットが作れるのでは…そう考えるのは自然な発想だろう。foussin もそう考えた。で、実際に作ってみたのが次のソース。
#!/usr/bin/perl
$NAME = 'ecalc_drop.pl';
$VERSION = '1.13';
$UPDATE = 'Mon 2010/07/26 12:12 JST'; # 'Day yyyy.mo.dd hh:mi JST'
$AUTHOR = 'pablo foussin(japan)'; # (c) pablo foussin
;# -----------------------------------------------
;# ユーザー設定【1】(日頃使っているエディタを指定)
;# -----------------------------------------------
$editor = '';
;# --------------------------------------------
;# ユーザー設定【2】(ecalc.pl のフルパスを指定)
;# --------------------------------------------
$ecalc = '';
;### 初期設定 ###
;# プラットフォームは Windows? それとも UNIX系(Linux)? どっち??
;# $ENV{'OS'} や $^O ではなく、$^X (Perlインタプリタのファイル名)で判断
$win = 0;
($^X =~ /\.exe$/) && ($win = 1);
;# $editor が空欄の場合、notepad(Windows) または vi(Linux) がデフォルト
;# のエディタとして設定される。$editor, notepad, vi の有無は調べない(あ
;# るものと断定している)。$editor に誤った指定がされている場合の実行結果
;# は保障できない。たぶん、エラー終了するだろう(手抜き)。
unless ($editor) {
$editor = "";
$win ? ($editor = "notepad") : ($editor = "vi");
}
;# ecalc.pl の有無を調べる(見つからなければ実行中止)
;# $ecalc, "./", $ENV{"PATH"} から ecalc.pl を探す
;# $ENV{"PATH"} の区切りは、Windows は『;』、UNIX系は『:』となる。
unless ($ecalc and -e $ecalc) {
$ecalc = "";
(-e "./ecalc.pl") && ($ecalc = "./ecalc.pl");
unless ($ecalc) {
$win ? ($sep = ";") : ($sep = ":");
$path = $ENV{"PATH"};
$path =~ tr|\\|/|; # path の区切りを『\』→『/』に置換
@path = split(/$sep/, $path);
foreach (@path) {
($_ eq '.' or $_ =~ /\/$/) && next;
(-e "$_/ecalc.pl") && ($ecalc = "$_/ecalc.pl");
$ecalc && last;
}
}
}
$ecalc || die "'ecalc.pl' not found!!\n";
;### 実行開始 ###
;# 書式特定(引数の有無で判断)
;# 引数は『ファイル名』…ファイルの検査は省略
;# 書式1: 入力ファイルを開く(ドラッグした場合を想定)
if ($ARGV[0]) {
$new_name = $tmp_name = $ifile = $ARGV[0];
;# $ifile の拡張子 → .tem かどうかを調べる
if ($tmp_name =~ /\.tem$/) {
($dd, $mm, $yy) = (localtime time)[3,4,5]; # 今日の年月日
++$mm;
$yy += 1900;
$dd = sprintf("%02d", $dd);
$mm = sprintf("%02d", $mm);
$ymd = "_" . $yy . "_" . $mm . "_" . $dd . ".txt";
$new_name =~ s/\.tem//;
$new_name .= $ymd;
open(IN, "<$tmp_name");
open(OUT,">$new_name");
while (<IN>) { print OUT $_; }
close(IN), close(OUT);
exec($editor, "$new_name");
;# 入力ファイルを ecalc.pl に渡す(メイン・ルーチン)
} else {
$result = $ifile . "_res.txt";
system("perl $ecalc < $ifile > $result");
exec($editor, "$result");
}
;# 書式2: 自分自身をエディタで開く(ダブルクリックした場合を想定)
} else {
exec($editor, "$0");
}
__END__
ご覧のとおり、冗長ライターを自称する foussin 作にしては簡潔なソースにまとまったと思う。で、このスクリプトだが、結果は…
…ということになった。ただし、Windows で動作させるためにも、ちょっと工夫が必要なので補足しておく。
バッチファイルとの違いは、必ずショートカットを作る必要があること、そしてショートカットの設定で『perl 』を追記する必要があることだ。しかし、このスクリプトを作った本来の目的は『Linux 用のドロップレット』の作成だった。が、その試みは失敗に終わった。
検証の結果、Linux でドロップレットを動作させるには、プログラムに『GUI のイベント』を認識する機能を追加する必要があることが分かった。要するに、『イベント駆動型(イベント・ドリブン)』のプログラムを組み込む必要がある。
これは、Perl、シェルスクリプトを問わず、その機能がないと『ドロップレット』が実現できないことを示している。その機能は…
…を利用すれば、比較的簡単に作成できそうだ。だが、新たに Tcl/Tk または Perl/Tk をインストールしなければならない。これは、ちょっと汎用性に欠ける。foussin としては…
…という信念を持ってプログラミングに取り組んでいるので、さらに『これも必要』『あれも必要』というのでは、ちょっと良くないと思っている。筆者自身、Tk の使い方を今から習得するというのは、さすがに面倒だし(興味はあるが)。
そんな訳で、Linux でのドロップレットの作成は断念した。ま、Linux ユーザーの場合、初級者の割合が Windows ユーザーほど多くないので、過剰な配慮は必要ないと思うけど。
このバッチにバグがあることが判明。ドロップレットとして実行する分には問題はないのだが、次のようにコンソール・ソフトとして実行すると問題が露見する。
c:\usr>ecalc exp.txt
これは、相対パスの解釈に曖昧な点があることが原因のようだ。この問題は、前項で紹介した『ecalc_drop.pl』でも起こることが判明。元々このバッチは、コマンドラインから実行することは想定していない。ドロップレットとして作成している。なので、このバグは当分は放置する。
可読性の悪いソースなので、修正するのが面倒だし、作者には、他にも制作を急いでいるプログラムがたくさん残っている。このバグに付き合っている暇はない。