moveメソッド実装

これでやっとファイルの移動処理が実装できたかな。すでに存在していたりする場合の処理もきちんと組めてるはず。List::Utilに依存するようになったけど、これはコアモジュールだしまあいいよね。List::MoreUtilsで定義されてるサブルーチン*1も使ってるけど、これには依存しない。なかったら自前のサブルーチンを使うように書いたから。具体的にはこう。

BEGIN {
    eval "use List::MoreUtils qw/all any/;";
    if ($@) {
        eval q{
            sub all (&@) {
                my $f = shift;
                foreach $_ (@_) { return if !$f->($_) }
                return 1;
            }
            sub any (&@) {
                my $f = shift;
                foreach $_ (@_) { return 1 if $f->($_) }
                return;
            }
        };
    }
}

BEGINブロックでevalを使ってList::MoreUtilsの読み込みを試みる。失敗したらそのときはまたevalで関数を定義。見ればわかるけど、両方eval EXPRです。まあ、2個目のはq{ };ってして、わざとBLOCKに見えるような書き方をしてますが。これ、eval BLOCKにしないのは当然わけありです。eval BLOCKを使うと、List::MoreUtilsが読み込めなかったときに、BEGINブロックでコンパイルエラーになって実行されないのです。eval EXPRを使うと、この制限を回避できるので、わざとこうなってるわけです。

追記 [10/09 03:45]

だめだ、よく考えたらまだ実装できてない! ダイジェストを求めてリネームするプラグインに対する動作は大丈夫。ハードリンクで複数のフォルダにまたがって存在する場合の考慮もできてる。だけどファイル名が同じであることとファイル内容が同一であることとにまったく関係のないプラグインの場合は今の実装だと失敗する。かならず古いほうを残して、今あるほうを削除しちゃう。そのあたりきちんとチェックしないといけないや。ダイジェストを求めて比較するか、File::Compareあたりで比較するか。なんにしても何らかの形で比べないといけない。いま気付けてよかったよ。

*1:allとany