Don't make a method object for calls to has_method, just for get_method
[gitmo/Class-MOP.git] / examples / ArrayBasedStorage.pod
CommitLineData
43715282 1
62189f84 2package # hide the package from PAUSE
f892c0f0 3 ArrayBasedStorage::Instance;
0e76a376 4
5use strict;
6use warnings;
8d2d4c67 7use Scalar::Util qw/refaddr/;
0e76a376 8
9use Carp 'confess';
10
11our $VERSION = '0.01';
8d2d4c67 12my $unbound = \'empty-slot-value';
0e76a376 13
14use base 'Class::MOP::Instance';
15
16sub new {
17 my ($class, $meta, @attrs) = @_;
18 my $self = $class->SUPER::new($meta, @attrs);
19 my $index = 0;
1fdb86fb 20 $self->{'slot_index_map'} = { map { $_ => $index++ } $self->get_all_slots };
0e76a376 21 return $self;
22}
23
24sub create_instance {
25 my $self = shift;
cf11901e 26 my $instance = bless [], $self->_class_name;
8d2d4c67 27 $self->initialize_all_slots($instance);
28 return $instance;
0e76a376 29}
30
f7259199 31sub clone_instance {
32 my ($self, $instance) = shift;
33 $self->bless_instance_structure([ @$instance ]);
34}
35
0e76a376 36# operations on meta instance
37
1fdb86fb 38sub get_slot_index_map { (shift)->{'slot_index_map'} }
62189f84 39
8d2d4c67 40sub initialize_slot {
41 my ($self, $instance, $slot_name) = @_;
42 $self->set_slot_value($instance, $slot_name, $unbound);
43}
44
45sub deinitialize_slot {
46 my ( $self, $instance, $slot_name ) = @_;
47 $self->set_slot_value($instance, $slot_name, $unbound);
48}
49
0e76a376 50sub get_all_slots {
51 my $self = shift;
f7259199 52 return sort $self->SUPER::get_all_slots;
0e76a376 53}
54
55sub get_slot_value {
56 my ($self, $instance, $slot_name) = @_;
1fdb86fb 57 my $value = $instance->[ $self->{'slot_index_map'}->{$slot_name} ];
8d2d4c67 58 return $value unless ref $value;
59 refaddr $value eq refaddr $unbound ? undef : $value;
0e76a376 60}
61
62sub set_slot_value {
63 my ($self, $instance, $slot_name, $value) = @_;
1fdb86fb 64 $instance->[ $self->{'slot_index_map'}->{$slot_name} ] = $value;
0e76a376 65}
66
0e76a376 67sub is_slot_initialized {
8d2d4c67 68 my ($self, $instance, $slot_name) = @_;
69 # NOTE: maybe use CLOS's *special-unbound-value* for this?
1fdb86fb 70 my $value = $instance->[ $self->{'slot_index_map'}->{$slot_name} ];
8d2d4c67 71 return 1 unless ref $value;
72 refaddr $value eq refaddr $unbound ? 0 : 1;
0e76a376 73}
74
da5680be 75sub is_dependent_on_superclasses { 1 }
76
0e76a376 771;
78
79__END__
80
81=pod
82
83=head1 NAME
84
f892c0f0 85ArrayBasedStorage - An example of an Array based instance storage
0e76a376 86
87=head1 SYNOPSIS
88
f892c0f0 89 package Foo;
90
1becdfcc 91 use metaclass (
f892c0f0 92 ':instance_metaclass' => 'ArrayBasedStorage::Instance'
93 );
94
95 __PACKAGE__->meta->add_attribute('foo' => (
96 reader => 'get_foo',
97 writer => 'set_foo'
98 ));
99
100 sub new {
101 my $class = shift;
102 $class->meta->new_object(@_);
103 }
104
105 # now you can just use the class as normal
106
0e76a376 107=head1 DESCRIPTION
108
f892c0f0 109This is a proof of concept using the Instance sub-protocol
110which uses ARRAY refs to store the instance data.
111
1becdfcc 112This is very similar now to the InsideOutClass example, and
113in fact, they both share the exact same test suite, with
114the only difference being the Instance metaclass they use.
115
1a09d9cc 116=head1 AUTHORS
0e76a376 117
118Stevan Little E<lt>stevan@iinteractive.comE<gt>
119
1a09d9cc 120Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
121
0e76a376 122=head1 SEE ALSO
123
124=head1 COPYRIGHT AND LICENSE
125
69e3ab0a 126Copyright 2006-2008 by Infinity Interactive, Inc.
0e76a376 127
128L<http://www.iinteractive.com>
129
130This library is free software; you can redistribute it and/or modify
131it under the same terms as Perl itself.
132
133=cut