個人的な感想かもしれませんが、Macはコマンドラインでの操作が苦になりませんが、Windowsだとドラッグ&ドロップの方がラクチンです。というのは、MacはEmacsエディターでほとんど作業をしているのでコマンドラインシェルをエディターの中から駆動するのですが、Windowsは秀丸エディターなどで作業するので、わざわざコマンドプロンプトを専用に開かないといけないからです。(本当に個人的な理由…)

 でも、ちょっとしたテキストベースの処理なんかは、やっぱりPerlでやりたい。この矛盾を解決するために、ドラッグ&ドロップでPerlのスクリプトを駆動することを覚えようと思いました。

Adam West as Batman
 大昔からですが、ActivePerlのbinの中に、pl2bat.batというバッチファイルがあります。これは、Perlのスクリプトをバッチファイルに変換してくれるスクリプトですが、これを使うと簡単にドラッグ&ドロップ対応になります。たとえば、以下のようなスクリプトを考えます。

#! /usr/local/bin/perl
# winTest.pl -- Windowsのテスト

use strict;
use warnings;
use Win32;

my $res = Win32::MsgBox("ARGV>@ARGV<");

 Win32というモジュールを使っていますが、これを使うとPerlでもダイアログボックス、ウィンドウをバリバリ使うきらびやかなプログラムが書けるらしいです。へー! でもここでは、引数を単純にメッセージボックスに表示するだけのプログラムを作ります。Windowsでしか実行しないので「/usr/local/bin/perl」というshebang行はおかしいのですが、いちおうコマンドラインで起動していいですか。

2016-225wintestpl

 にゃるほど。これをC:\Perl\bin\pl2bat.plにドラッグ&ドロップします。

2016-225dd

 winTest.batというバッチファイルがwinTest.plと同じデスクトップにできます。

2016-225bat

 では、このバッチファイルに、まずは単一のファイルをドラッグ&ドロップします。下では、winTest.plをバッチファイルにドラッグ&ドロップしてみました。

2016-225file

 ふむふむ。ファイルの絶対パス名が表示されますね。ちなみに、複数のファイルをドラッグ&ドロップすると、@ARGVの各要素に入ります。
 続いてディレクトリ(フォルダー)をドラッグ&ドロップします。以下ではC:\Users\cf\xyzzyというフォルダーをドラッグ&ドロップしました。

2016-225foldere

 これもフォルダーの名前が@ARGVに入ります。

 変換された、winTest.plの中身を眺めてみます。

@rem = '--*-Perl-*--
@echo off
if "%OS%" == "Windows_NT" goto WinNT
perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
goto endofperl
:WinNT
perl -x -S %0 %*
if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
if %errorlevel% == 9009 echo You do not have Perl in your PATH.
if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
goto endofperl
@rem ';
#! /usr/local/bin/perl
#line 15
# winTest.pl -- Windowsのテスト

use strict;
use warnings;
use Win32;

my $res = Win32::MsgBox("ARGV>@ARGV<");

__END__
:endofperl

 最初にOSがWindows NTベースの最近のOSかで分岐しています。基本Windows XP以降はNT系なので、ほとんどのご家庭にあるWindowsはWindows_NTだと思います。

perl -x -S %0 %*

 で、perlコマンドを-x、-Sというスイッチとともに%0、%*を渡して実行しています。
 ここで%0は自分自身、つまり、winTest.batです。
 ですからこのファイルは、まずバッチファイルとして実行され、そのあと自分自身をPerlスクリプトとして解釈します。

 -xは、

#! /usr/local/bin/perl

までの行を無視します。ですからファイルの先頭のバッチファイル部分を読み飛ばしてくれます。

 -Sは、環境変数PATHによってプログラム(ここでいう%0)を探します。もし%0に完全パスが入っていないときに有効です。ですが、

my $res = Win32::MsgBox("$0 ARGV>@ARGV<");

のように$0(プログラム名)も表示するように実行すると、ちゃんとフルパス名が入っていました。

2016-225zero

 余談ですが、PerlではなくWindowsの機能ですが、このダイアログボックスが前面に出ている状態でCtrl+Cを押すと、ちらりんという警告音が出るところではあるんですが、ダイアログボックスの中身がクリップボードにコピーされます。

---------------------------
Perl
---------------------------
C:\Users\cf\Desktop\winTest.bat ARGV>C:\Users\cf\Desktop\winTest.pl<
---------------------------
OK
---------------------------


 これは便利ですね。何らかのアプリのテストをしているときに重宝します。

perl -x -S %0 %*

に戻りますが、%0はプログラム名(C:\Users\cf\Desktop\winTest.bat)です。$*は@ARGVですね。Windows 95系はこれが使えなかったために

perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9

という手法(引数9個限定)を取っていたんですね。

 そのあともろもろチェックがあって、プログラムを実行したあとは

:endofperl

に飛んでいます。

 ということでいろいろ便利そうですが、本格的に便利に使うのはまた明日の心だぁ~!