ОБНОВЛЕНИЕ
Теперь есть намного лучший способ сделать это, используйте MooseX :: ClassAttribute
Тогда просто используйте class_has
вместо has
для методов, которые вы хотите использовать совместно со всеми экземплярами.
package My::Class;
use Moose;
use MooseX::ClassAttribute;
class_has 'Cache' =>
( is => 'rw',
isa => 'HashRef',
default => sub { {} },
);
__PACKAGE__->meta()->make_immutable();
OLD
Кроме того, существует ли шаблон проектирования, который описывает это поведение?
Да.Это называется синглтон.Синглтон - это шаблон, в котором несколько инициаций (вызовы ->new
) возвращают один и тот же объект.Вы можете сделать это так или сохранить переменную вне класса.Moose предоставляет слой, который позволит вам легко создавать синглтоны (хотя в любом случае это не особенно сложно): модуль MooseX :: Singleton .Moose также позволяет вам делегировать другому объекту, используя аксессор .
. Здесь мы используем MooseX :: Singleton и переход к скрытому атрибуту для достижения желаемогоЭффект.
package MySingleton;
use MooseX::Singleton;
has 'foo' => ( is => 'rw', isa => 'Bool', default => 0 );
package ClassA;
use Moose;
has '_my_singleton' => (
isa => 'MySingleton'
, is => 'ro'
, default => sub { MySingleton->new }
, handles => [qw( foo )]
);
package ClassB;
use Moose;
has '_my_singleton' => (
isa => 'MySingleton'
, is => 'ro'
, default => sub { MySingleton->new }
, handles => [qw( foo )]
);
package main;
use Test::More tests => 5;
my $class_a = ClassA->new;
my $class_b = ClassA->new;
is( $class_a->foo(0), 0, 'Set A to false' );
is( $class_a->foo, 0, 'A Is false' );
is( $class_b->foo, 0, 'B Is false' );
is( $class_b->foo(1), 1, 'Set B to true' );
is( $class_a->foo, 1, 'A is true' );
Или без MooseX
Пожалуйста, не делайте этого без необходимости.Метод MooseX гораздо приятнее:
package Underclass;
use Moose;
has 'foo' => ( is => 'rw', isa => 'Bool', default => 0 );
package SingletonWrapper;
my $obj;
sub new {
if ( $obj ) { return $obj; }
else { $obj = Underclass->new }
}
package ClassA;
use Moose;
has '_my_singleton' => (
isa => 'Underclass'
, is => 'ro'
, default => sub { SingletonWrapper->new }
, handles => [qw( foo )]
);
package ClassB;
use Moose;
has '_my_singleton' => (
isa => 'Underclass'
, is => 'ro'
, default => sub { SingletonWrapper->new }
, handles => [qw( foo )]
);