1

我有几个模块具有许多与日期时间相关的属性,这些属性接受日期戳并返回人类可读的字符串( dd Mon yyyy hh:mm:ss )。

package ModuleOne;

use Moose;

extends 'ModuleBase';

has date_attr_one => ( ... );

进而 ...

package ModuleTwo;

use Moose;

extends 'ModuleBase';

has date_attr_mouse => ( ... );

由于它目前正在工作,我正在使用“around”属性修饰符,这样如果没有参数,则返回格式为“2012 年 5 月 3 日 12:33:42”的日期。如果有格式为“2012 年 5 月 3 日 12:33:42”的参数,我想将其设置为日期戳。

所以,在 ModuleOne 中,会有:

has date_attr_one => ( ... );

其次是:

around 'date_attr_one' => sub { ... }

第二个模块中发生了相同类型的事情。

我遇到的问题是有多个模块在执行此操作,并且每个模块都使用“around”修饰符和相同的重复代码。我想将修饰符移动到基类中,以便扩展基类的每个模块都可以使用该修饰符。我尝试使用正则表达式将其放入基类中:(在基类中)

around qr/date_attr_one/ => sub { ... }

我在那里放了一些从未执行过的打印语句。角色不允许这样的事情。

有没有办法将修饰符移动到基类中,以便扩展基类的每个模块都可以使用该修饰符,其中属性在每个模型中具有不同的名称?

因此,如上例所示,属性修饰符周围的基类将需要处理 $self->date_attr_one 和 $self->date_attr_mouse 等。

4

1 回答 1

2

如果您创建一个如下所示的包,那么您在类中所需要的只是:

has date => (
   is     => 'rw',
   isa    => 'My::Date',
   coerce => 1,
);

示例代码:

my $o = My::Class->new(date => '03 May 2012 12:33:42');
say $o->date();
say 0+$o->date();

$o->date(1336062822);
say $o->date();
say 0+$o->date();

上述模块:

package My::Date;

use strict;
use warnings;

use Moose;
use Moose::Util::TypeConstraints;

use DateTime::Format::Strptime qw( );
use POSIX                      qw( strftime );

my $format = DateTime::Format::Strptime->new(
   pattern   => '%d %b %Y %H:%M:%S',
   locale    => 'en_US',
   time_zone => 'local',
   on_error  => 'croak',
);

has epoch => (
   is       => 'rw',
   isa      => 'Num',
   required => 1,
);

sub as_string {
   return strftime('%d %b %Y %H:%M:%S', localtime( $_[0]->epoch ));
}

coerce __PACKAGE__,
   from 'Num',
      via { __PACKAGE__->new( epoch => $_ ) },
   from 'Str',
      via { __PACKAGE__->new( epoch => $format->parse_datetime($_)->epoch ) };

use overload (
   '""' => sub { $_[0]->as_string },
   '0+' => sub { $_[0]->epoch },
   fallback => 1,
);

1;
于 2012-05-09T01:33:47.097 回答