2 package MooseX::Singleton::Meta::Instance;
4 use Scalar::Util 'weaken';
6 extends 'Moose::Meta::Instance';
8 sub get_singleton_instance {
9 my ($self, $instance) = @_;
11 return $instance if blessed $instance;
13 # optimization: it's really slow to go through new_object for every access
14 # so return the singleton if we see it already exists, which it will every
15 # single except the first.
17 return ${"$instance\::singleton"} if defined ${"$instance\::singleton"};
19 # We need to go through ->new in order to make sure BUILD and
20 # BUILDARGS get called.
21 return $instance->meta->name->new;
25 my ($self, $instance) = @_;
26 $self->get_singleton_instance($instance);
30 my ($self, $instance, $slot_name) = @_;
31 $self->is_slot_initialized($instance, $slot_name) ? $self->get_singleton_instance($instance)->{$slot_name} : undef;
35 my ($self, $instance, $slot_name, $value) = @_;
36 $self->get_singleton_instance($instance)->{$slot_name} = $value;
39 sub deinitialize_slot {
40 my ( $self, $instance, $slot_name ) = @_;
41 delete $self->get_singleton_instance($instance)->{$slot_name};
44 sub is_slot_initialized {
45 my ($self, $instance, $slot_name, $value) = @_;
46 exists $self->get_singleton_instance($instance)->{$slot_name} ? 1 : 0;
49 sub weaken_slot_value {
50 my ($self, $instance, $slot_name) = @_;
51 weaken $self->get_singleton_instance($instance)->{$slot_name};
54 sub inline_slot_access {
55 my ($self, $instance, $slot_name) = @_;
56 sprintf "%s->meta->instance_metaclass->get_singleton_instance(%s)->{%s}", $instance, $instance, $slot_name;
69 MooseX::Singleton::Meta::Instance
73 This instance metaclass manages attribute access and storage. When accessing an
74 attribute, it will convert a bare package to its cached singleton instance
75 (creating it if necessary).