cdif v2.5

昨年末に更新した cdif を修正しました。

未修正部分の着色に対応

自分では必要ないと思っているのですが、未修整部分の文字にも色を付けられるようにしました。 また --colormap というオプションで、それぞれのフィールドの色を指定できるようになっています。 デフォルトの設定はこう。

cdif --cm 'COMMAND=SE,OMARK=CS,NMARK=MS' \
     --cm '*TEXT=,*CHANGE=BDw,DELETE=APPEND=RDw'

--commandcolor, --markcolor, --textcolor オプションで、フィールドに色を付けるかどうかを指示することもできます。 --cc, --mc, --tc とも省略可。 デフォルトでは --notc になっています。

f:id:uta46:20140111102309j:plain

あ、DELETE がなかった…

diff -t, -T に対応

その他、若干のバグ修正

ところで

今回、--colormap オプションをテーブルに反映する部分のコードはこんな風になっています。

if (@opt_colormap) {
    map {
        my $c = pop @$_;
        map { $colormap{$_} = $c }
        map { match_glob $_, keys %colormap }
        @$_;
    }
    map { [ split /=/, $_, -1 ] }
    map { split /,/ }
    @opt_colormap;
}

自分で書いといて、なんだか Perl っぽくないコードだなあと時代を感じたりするわけですが、3行目だけ古風な感じなので List::Util の reduce を使って書き直そうかと思うと、これがどうもうまくいかないのですよ。 次のプログラムを実行すると、$hash{k1}, $hash{k2} に v が入ってほしいのだけど、2番目は undef になってしまいます。

my %hash;
reduce {
    $hash{$b} = $a;
    $a;
} qw(v k1 k2);
print Dumper \%hash;

$a は一度代入すると値を失うようで、$a; だけの行を削除すると動くし(この行は本来不必要)、代入する部分を "$a" にしても大丈夫。 どうも perl5.12 に含まれる reduce のバグではないかと。 List::Util::PP を使えば動作するし。

なんとか使う方法はわかり、map と reduce だけのそれなりに趣のあるコードになりますが、動いたところで変な warning は出るし、無駄に可読性を下げるだけなので不採用でした。 参考のために一応見せるとこんなです。

use List::Util qw(reduce);
no warnings;

if (@opt_colormap) {
    map {
        reduce {
            map { $colormap{$_} = "$a" } match_glob $b, keys %colormap;
        } reverse @$_;
    }
    map { [ split /=/, $_, -1 ] }
    map { split /,/ }
    @opt_colormap;
}