ここで、DateTime系って言ってるのは、DateTimeモジュールのことではないです。
自作する場合(wrapperでもなんでも)、みたいな話。
例えば、Time::Pieceのように
$d += DAY * 5; $d += MONTH * 3;
なんてことをしたい。
ただ、Time::PieceのTime::Secondsに定義されているMONTHとかは、単純に秒数なので、1/31 + 1 * MONTH = 2/28 みたいなことはしてくれない。
で、次のようなものを考えた。
package Hoge::DateTime::Unit; use strict; use Carp (); use Readonly; use overload '""' => sub { shift }; use overload '*' => sub { my $self = shift; return $self->_multiply(@_) }; use overload 'bool' => sub { my $self = shift; return $$self }; # new is used to create constant value. so $unit shouldn't be modified. sub new { my $class = shift; Readonly my $unit => 1; return bless \$unit, $class; } sub _multiply { my $class = ref(my $self = shift); my $unit = $$self * shift; return bless \$unit, $class; } package Hoge::DateTime::Month; use base qw/Hoge::DateTime::Unit/; package Hoge::DateTime::Year; use base qw/Hoge::DateTime::Unit/; package Hoge::DateTime::Weekday; use base qw/Hoge::DateTime::Unit/; 1;
とかしてやって、DateTime系のモジュールで、 次のようにconstant定義する。
package Hoge::DateTime; use constant { YEAR => Hoge::DateTime::YEAR->new, MONTH => Hoge::DateTime::Month->new, WEEKDAY => Hoge::DateTime::Weekday->new, # 営業日 DAY => 60 * 60 * 24, HOUR => 60 * 60, MINUTE => 60, SECOND => 1, };
オブジェクトに +/- されるときに、classを調べて、挙動を変えてあげると、
$d = Hoge::DateTime->new("2007-01-31"); $d += MONTH * 1; # 2007-02-28 $d += WEEKDAY * 7; # 2007-03-09 $d += YEAR * 1; # 2008-03-09
みたいなのが出来るなぁとか思った。それだけ。