DateTime::Format::Strptime にパッチを送った話 #Perl
CPAN モジュールの DateTime::Format::Strptime は DateTime と同じ Dave Rolsky さんが開発しているもので、日付時刻を含む文字列のパースによく使われているのではないかと思います。
このモジュールの挙動が v1.58 から変わっていました。
#!perl use feature qw(say); use DateTime::Format::Strptime; my $strp = DateTime::Format::Strptime->new( pattern => '%Y%m%d', ); for my $str (qw/20160330 access_log.20160330/) { my $dt = $strp->parse_datetime($str); say "$str => undef " and next unless $dt; say "$str => " . $strp->format_datetime($dt); }
これを実行すると、下のようになりました。
# v1.57 以前 20160330 => 20160330 access_log.20160330 => 20160330 # v1.58 以降 20160330 => 20160330 access_log.20160330 => undef
そう。
日付時刻を表す文字列の前に、別の文字列があるようなものはパースできなくなっていたのです。
Changes や差分を見ていたところ、どうやら v1.57 〜 v1.60 の間に互換性を崩す大幅な変更があったようです。
ので、仕様変更かなーと同僚の間で話していたのですが、作者に聞くのが確実だろうと思ったので、GitHub の Issued で聞いてみました。
なんとバグだったようです。
せっかくなので、直せるかどうか手元でやってみることにしました。
GitHub で fork して、まずはテストを書いて再現させてみました。
テストを書いたところ、どうやら 20160330.log
のように、後ろに文字列があるケースはパースできるということに気がつきました。
…で、試行錯誤した結果、正規表現を数文字変えれば問題の挙動が直り、既存のテストも通るということがわかりました。
ので、Pull Request を送りました。
取り込まれる過程で少し修正されていましたが、めでたく修正版の v1.67 がリリースされました。
めでたしめでたし。