======================================================= Object-Oriented Programming with Perl Vol.26 by Tatsuhiko Miyagawa ======================================================= 1. 2001/09/09 問題 ________________ 2001年9月9日が近づいて来ました。この日(*1)、UNIX epoch (1970/01/01) か らの timestamp が初めて桁上がりして10桁になります。いまどき、timestamp を固定長文字列で扱っているアプリケーションも少ないでしょうから、問題は 起こりにくいでしょう。ただ、フロントエンドのアプリケーションに Perl を 使っている場合、sort 関数の取扱いに注意が必要です。 *1) 正確には % perl -le 'print scalar localtime(1_000_000_000)' Sun Sep 9 10:46:40 2001 2. Dunce::time __________________ Perl の sort 関数はコードブロックに何も与えない場合、文字列としての比 較を行います。数値として比較したければ、明示的に指定する必要があります。 % perl -le 'print join " ", sort 1, 2, 10' 1 10 2 % perl -le 'print join " ", sort { $a <=> $b } 1, 2, 10' 1 2 10 よって、time() 関数で取得した timestamp を、何も考えずに sort() に渡し た場合、桁上がりをきっかけに、前後関係が狂ってしまうことが想定されます。 そこで、time() の文字列比較をトラップするモジュール Dunce::time をつくっ てみました。CPAN にもアップロードしてあります。 Dunce::time http://search.cpan.org/search?dist=Dunce-time 単なるアイデアもので、ビルトイン time() 関数を上書きして、数値でなくオ ブジェクトリファレンスを書くようにします。そして、演算子オーバーロード を利用して、文字列比較をトラップする、というだけです。 似たようなモジュールに、Y2K をトラップする D'oh-Year というのがありま す。というより、このモジュールのドキュメントにあった TODO を実装してみ ただけだったりしますが。 D'oh-Year http://search.cpan.org/search?dist=D-oh-Year 3. 演算子オーバーロード _____________ Perl 5 のオーバーロード機能はシンプルに実装できます。overload プラグマ によって、オーバーロードする演算子と、対応するメソッドを定義します。 package Foo; use overload '""' => \&as_string; sub as_string { return 'foo'; } このようにすれば、Foo クラスのインスタンスを文字列に落す場合には、'foo' という文字として評価されます。 package main; my $foo = bless {}, 'Foo'; print $foo; # "foo" Dunce::time では、文字列比較 (cmp) をオーバーロードし、例外を上げる (*2)ようにしています。よって、データベースなどにいったん落したものを文 字列比較する場合には、残念ながら効果はないです。 詳しくは perldoc overload, Dunce::time のソースをご覧ください。 *2) import オプションで warning や自動修正するようにもできます. -- OOP w/ Perl http://bulknews.net/lib/