diff options
Diffstat (limited to 'lib/MooseX/ArrayRef/Meta/Role/Instance.pm')
-rw-r--r-- | lib/MooseX/ArrayRef/Meta/Role/Instance.pm | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/lib/MooseX/ArrayRef/Meta/Role/Instance.pm b/lib/MooseX/ArrayRef/Meta/Role/Instance.pm new file mode 100644 index 0000000..1258e79 --- /dev/null +++ b/lib/MooseX/ArrayRef/Meta/Role/Instance.pm @@ -0,0 +1,88 @@ +package MooseX::ArrayRef::Meta::Role::Instance; +use Moose::Role; + +my $NOT_EXISTS = \undef; + +has slot_mapping => ( + traits => ['Hash'], + isa => 'HashRef[Int]', + lazy => 1, + default => sub { + my $self = shift; + my @order = $self->_sorted_slots; + return { map { $order[$_] => $_ } 0..$#order }; + }, + handles => { + slot_index => 'get', + num_slots => 'count', + }, +); + +sub _sorted_attributes { + my $self = shift; + return sort { + my ($a_name, $b_name) = map { $_->associated_class->name } ($a, $b); + $a_name eq $b_name + ? $a->insertion_order <=> $b->insertion_order + : $a_name->isa($b_name) + ? 1 + : -1; + + } $self->get_all_attributes; +} + +sub _sorted_slots { + my $self = shift; + return map { sort $_->slots } $self->_sorted_attributes; +} + +sub create_instance { + my $self = shift; + bless [($NOT_EXISTS) x $self->num_slots], $self->_class_name; +} + +sub clone_instance { + my ($self, $instance) = @_; + bless [ @$instance ], $self->_class_name; +} + +sub get_slot_value { + my ($self, $instance, $slot_name) = @_; + my $val = $instance->[$self->slot_index($slot_name)]; + return $val unless ref($val); + return undef if $val == $NOT_EXISTS; + return $val; +} + +sub set_slot_value { + my ($self, $instance, $slot_name, $value) = @_; + $instance->[$self->slot_index($slot_name)] = $value; +} + +sub initialize_slot { + my ($self, $instance, $slot_name) = @_; + $instance->[$self->slot_index($slot_name)] = $NOT_EXISTS; +} + +sub deinitialize_slot { + my ($self, $instance, $slot_name) = @_; + $instance->[$self->slot_index($slot_name)] = $NOT_EXISTS; +} + +sub is_slot_initialized { + my ($self, $instance, $slot_name) = @_; + my $val = $instance->[$self->slot_index($slot_name)]; + !ref($val) || $val != $NOT_EXISTS; +} + +sub weaken_slot_value { + my ($self, $instance, $slot_name) = @_; + weaken $instance->[$self->slot_index($slot_name)]; +} + +# TODO +sub is_inlinable { 0 } + +no Moose::Role; + +1; |