#!/usr/bin/env perl package MooseX::Singleton::Meta::Instance; use Moose; use Scalar::Util 'weaken'; extends 'Moose::Meta::Instance'; sub get_singleton_instance { my ($self, $instance) = @_; return $instance if blessed $instance; # optimization: it's really slow to go through new_object for every access # so return the singleton if we see it already exists, which it will every # single except the first. no strict 'refs'; return ${"$instance\::singleton"} if defined ${"$instance\::singleton"}; return $instance->meta->construct_instance; } sub clone_instance { my ($self, $instance) = @_; $self->get_singleton_instance($instance); } sub get_slot_value { my ($self, $instance, $slot_name) = @_; $self->is_slot_initialized($instance, $slot_name) ? $self->get_singleton_instance($instance)->{$slot_name} : undef; } sub set_slot_value { my ($self, $instance, $slot_name, $value) = @_; $self->get_singleton_instance($instance)->{$slot_name} = $value; } sub deinitialize_slot { my ( $self, $instance, $slot_name ) = @_; delete $self->get_singleton_instance($instance)->{$slot_name}; } sub is_slot_initialized { my ($self, $instance, $slot_name, $value) = @_; exists $self->get_singleton_instance($instance)->{$slot_name} ? 1 : 0; } sub weaken_slot_value { my ($self, $instance, $slot_name) = @_; weaken $self->get_singleton_instance($instance)->{$slot_name}; } sub inline_slot_access { my ($self, $instance, $slot_name) = @_; sprintf "%s->meta->instance_metaclass->get_singleton_instance(%s)->{%s}", $instance, $instance, $slot_name; } 1; __END__ =pod =head1 NAME MooseX::Singleton::Meta::Instance =head1 DESCRIPTION This instance metaclass manages attribute access and storage. When accessing an attribute, it will convert a bare package to its cached singleton instance (creating it if necessary). =cut