如何在初始化后定义Moose对象子程序?

Dav*_*d B 2 perl initialization moose

如何在初始化后定义Moose对象子程序?

我正在使用Moose编写一个对象模块,我计划序列化(nstore)创建的对象.

检查以下(简化!)示例:

package MyObj 0.001;

use Moose;
use namespace::autoclean;

has 'size' => (
 is       => 'ro',
 isa      => 'Int',
 required => 1,
);

sub some_sub {
 my ($self, @more) = @_;
 if ($self->size() < 100) # do something;
 elsif (($self->size() < 500)) # do something else;
 elsif (($self->size() < 7500)) # do something else;
 # ...
}

1;
Run Code Online (Sandbox Code Playgroud)

some_sub行为不同取决于size.由于它size是只读的,因此在初始化对象后它保持不变.

所以,假设我打了some_sub几十万次,很遗憾我if每次都必须经历所有的事情.

在对象初始化之后我最好这样做一次,然后设置some_sub为更简单的函数,根本没有ifs.

但是......我怎么能这样做?

UPDATE

也许我应该添加一个lazysubref类型的属性,它将保存对所选子例程的引用.some_sub然后会打电话$self->chosen_sub->(@_).你怎么看?

hdp*_*hdp 5

has calculation_method => (is => 'ro', lazy_build => 1, init_arg => undef);

sub _build_calculation_method {
    my $self = shift;
    return '_calculate_small'  if $self->size < 100;
    return '_calculate_medium' if $self->size < 500;
    return '_calculate_large'  if $self->size < 7500;
    return '_calculate_enormous';
}

sub _calculate_small  { ... }
sub _calculate_medium { ... }
# etc.

sub calculate {
    my $self = shift;
    my $method = $self->calculation_method;
    return $self->$method(@_);
}
Run Code Online (Sandbox Code Playgroud)

作为奖励,calculation_method现在也可以序列化.