added the AUTHORITY into all classes, and support for it into Module
[gitmo/Class-MOP.git] / lib / Class / MOP / Instance.pm
CommitLineData
24869f62 1
2package Class::MOP::Instance;
3
4use strict;
5use warnings;
6
fa16e528 7use Scalar::Util 'weaken', 'blessed';
24869f62 8
f0480c45 9our $VERSION = '0.03';
10our $AUTHORITY = 'cpan:STEVAN';
24869f62 11
12sub meta {
13 require Class::MOP::Class;
14 Class::MOP::Class->initialize(blessed($_[0]) || $_[0]);
15}
16
17sub new {
052c2a1a 18 my ($class, $meta, @attrs) = @_;
c57c8b10 19 my @slots = map { $_->slots } @attrs;
24869f62 20 bless {
fc3ddd1d 21 # NOTE:
22 # I am not sure that it makes
23 # sense to pass in the meta
24 # The ideal would be to just
25 # pass in the class name, but
26 # that is placing too much of
27 # an assumption on bless(),
28 # which is *probably* a safe
29 # assumption,.. but you can
30 # never tell <:)
49c93440 31 meta => $meta,
f7259199 32 slots => { map { $_ => undef } @slots },
24869f62 33 } => $class;
34}
35
49c93440 36sub create_instance {
37 my $self = shift;
38 $self->bless_instance_structure({});
2d711cc8 39}
40
49c93440 41sub bless_instance_structure {
42 my ($self, $instance_structure) = @_;
43 bless $instance_structure, $self->{meta}->name;
2d711cc8 44}
45
f7259199 46sub clone_instance {
47 my ($self, $instance) = @_;
48 $self->bless_instance_structure({ %$instance });
49}
50
2d711cc8 51# operations on meta instance
52
eb49acde 53sub get_all_slots {
54 my $self = shift;
f7259199 55 return keys %{$self->{slots}};
56}
57
58sub is_valid_slot {
59 my ($self, $slot_name) = @_;
60 exists $self->{slots}->{$slot_name} ? 1 : 0;
839ea973 61}
62
2d711cc8 63# operations on created instances
64
839ea973 65sub get_slot_value {
2bab2be6 66 my ($self, $instance, $slot_name) = @_;
67 return $instance->{$slot_name};
839ea973 68}
69
2bab2be6 70sub set_slot_value {
71 my ($self, $instance, $slot_name, $value) = @_;
72 $instance->{$slot_name} = $value;
73}
74
2d711cc8 75sub initialize_slot {
49c93440 76 my ($self, $instance, $slot_name) = @_;
d82060fe 77 $self->set_slot_value($instance, $slot_name, undef);
2d711cc8 78}
79
7d28758b 80sub deinitialize_slot {
81 my ( $self, $instance, $slot_name ) = @_;
82 delete $instance->{$slot_name};
83}
84
c174112e 85sub initialize_all_slots {
86 my ($self, $instance) = @_;
87 foreach my $slot_name ($self->get_all_slots) {
88 $self->initialize_slot($instance, $slot_name);
89 }
90}
91
7d28758b 92sub deinitialize_all_slots {
93 my ($self, $instance) = @_;
94 foreach my $slot_name ($self->get_all_slots) {
95 $self->deinitialize_slot($instance, $slot_name);
96 }
97}
98
49c93440 99sub is_slot_initialized {
100 my ($self, $instance, $slot_name, $value) = @_;
2d711cc8 101 exists $instance->{$slot_name} ? 1 : 0;
2bab2be6 102}
839ea973 103
5582521c 104sub weaken_slot_value {
105 my ($self, $instance, $slot_name) = @_;
106 weaken $instance->{$slot_name};
107}
108
109sub strengthen_slot_value {
110 my ($self, $instance, $slot_name) = @_;
111 $self->set_slot_value($instance, $slot_name, $self->get_slot_value($instance, $slot_name));
112}
113
ee7c0467 114# inlinable operation snippets
115
c0cbf4d9 116sub is_inlinable { 1 }
117
118sub inline_create_instance {
119 my ($self, $class_variable) = @_;
120 'bless {} => ' . $class_variable;
121}
122
ee7c0467 123sub inline_slot_access {
124 my ($self, $instance, $slot_name) = @_;
125 sprintf "%s->{%s}", $instance, $slot_name;
126}
127
128sub inline_get_slot_value {
129 my ($self, $instance, $slot_name) = @_;
130 $self->inline_slot_access($instance, $slot_name);
131}
132
133sub inline_set_slot_value {
134 my ($self, $instance, $slot_name, $value) = @_;
135 $self->inline_slot_access($instance, $slot_name) . " = $value",
136}
137
138sub inline_initialize_slot {
139 my ($self, $instance, $slot_name) = @_;
140 $self->inline_set_slot_value($instance, $slot_name, 'undef'),
141}
142
7d28758b 143sub inline_deinitialize_slot {
144 my ($self, $instance, $slot_name) = @_;
145 "delete " . $self->inline_slot_access($instance, $slot_name);
146}
ee7c0467 147sub inline_is_slot_initialized {
148 my ($self, $instance, $slot_name) = @_;
149 "exists " . $self->inline_slot_access($instance, $slot_name) . " ? 1 : 0";
150}
151
152sub inline_weaken_slot_value {
153 my ($self, $instance, $slot_name) = @_;
154 sprintf "Scalar::Util::weaken( %s )", $self->inline_slot_access($instance, $slot_name);
155}
156
157sub inline_strengthen_slot_value {
158 my ($self, $instance, $slot_name) = @_;
159 $self->inline_set_slot_value($instance, $slot_name, $self->inline_slot_access($instance, $slot_name));
160}
161
24869f62 1621;
163
164__END__
165
166=pod
167
168=head1 NAME
169
170Class::MOP::Instance - Instance Meta Object
171
172=head1 SYNOPSIS
173
9fa4d0b4 174 # for the most part, this protocol is internal
175 # and not for public usage, but this how one
176 # might use it
177
178 package Foo;
179
180 use strict;
181 use warnings;
1becdfcc 182 use metaclass (
9fa4d0b4 183 ':instance_metaclass' => 'ArrayBasedStorage::Instance',
184 );
185
186 # now Foo->new produces blessed ARRAY ref based objects
187
24869f62 188=head1 DESCRIPTION
189
9fa4d0b4 190This is a sub-protocol which governs instance creation
191and access to the slots of the instance structure.
192
193This may seem like over-abstraction, but by abstracting
194this process into a sub-protocol we make it possible to
195easily switch the details of how an object's instance is
196stored with minimal impact. In most cases just subclassing
1becdfcc 197this class will be all you need to do (see the examples;
198F<examples/ArrayBasedStorage.pod> and
199F<examples/InsideOutClass.pod> for details).
9fa4d0b4 200
24869f62 201=head1 METHODS
202
203=over 4
204
9fa4d0b4 205=item B<new ($meta, @attrs)>
206
207Creates a new instance meta-object and gathers all the slots from
208the list of C<@attrs> given.
209
210=item B<meta>
211
212This will return a B<Class::MOP::Class> instance which is related
213to this class.
214
215=back
216
217=head2 Creation of Instances
218
219=over 4
24869f62 220
58287a97 221=item B<create_instance>
222
9fa4d0b4 223This creates the appropriate structure needed for the instance and
224then calls C<bless_instance_structure> to bless it into the class.
0e76a376 225
9fa4d0b4 226=item B<bless_instance_structure ($instance_structure)>
839ea973 227
9fa4d0b4 228This does just exactly what it says it does.
0e76a376 229
f7259199 230=item B<clone_instance ($instance_structure)>
231
9fa4d0b4 232=back
839ea973 233
9fa4d0b4 234=head2 Instrospection
58287a97 235
9fa4d0b4 236NOTE: There might be more methods added to this part of the API,
237we will add then when we need them basically.
58287a97 238
9fa4d0b4 239=over 4
240
241=item B<get_all_slots>
242
243This will return the current list of slots based on what was
244given to this object in C<new>.
58287a97 245
f7259199 246=item B<is_valid_slot ($slot_name)>
247
24869f62 248=back
249
9fa4d0b4 250=head2 Operations on Instance Structures
251
252An important distinction of this sub-protocol is that the
253instance meta-object is a different entity from the actual
254instance it creates. For this reason, any actions on slots
255require that the C<$instance_structure> is passed into them.
24869f62 256
257=over 4
258
9fa4d0b4 259=item B<get_slot_value ($instance_structure, $slot_name)>
24869f62 260
9fa4d0b4 261=item B<set_slot_value ($instance_structure, $slot_name, $value)>
262
263=item B<initialize_slot ($instance_structure, $slot_name)>
264
7d28758b 265=item B<deinitialize_slot ($instance_structure, $slot_name)>
266
9fa4d0b4 267=item B<initialize_all_slots ($instance_structure)>
268
7d28758b 269=item B<deinitialize_all_slots ($instance_structure)>
270
9fa4d0b4 271=item B<is_slot_initialized ($instance_structure, $slot_name)>
24869f62 272
ee7c0467 273=item B<weaken_slot_value ($instance_structure, $slot_name)>
274
275=item B<strengthen_slot_value ($instance_structure, $slot_name)>
276
277=back
278
279=head2 Inlineable Instance Operations
280
f7259199 281This part of the API is currently un-used. It is there for use
282in future experiments in class finailization mostly. Best to
283ignore this for now.
284
ee7c0467 285=over 4
286
c0cbf4d9 287=item B<is_inlinable>
288
289Each meta-instance should override this method to tell Class::MOP if it's
290possible to inline the slot access.
291
292This is currently only used by Class::MOP::Class::Immutable when performing
293optimizations.
294
495af518 295=item B<inline_create_instance>
296
ee7c0467 297=item B<inline_slot_access ($instance_structure, $slot_name)>
298
299=item B<inline_get_slot_value ($instance_structure, $slot_name)>
300
301=item B<inline_set_slot_value ($instance_structure, $slot_name, $value)>
302
303=item B<inline_initialize_slot ($instance_structure, $slot_name)>
304
7d28758b 305=item B<inline_deinitialize_slot ($instance_structure, $slot_name)>
306
ee7c0467 307=item B<inline_is_slot_initialized ($instance_structure, $slot_name)>
5582521c 308
ee7c0467 309=item B<inline_weaken_slot_value ($instance_structure, $slot_name)>
5582521c 310
ee7c0467 311=item B<inline_strengthen_slot_value ($instance_structure, $slot_name)>
5582521c 312
24869f62 313=back
314
1a09d9cc 315=head1 AUTHORS
24869f62 316
9fa4d0b4 317Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
318
24869f62 319Stevan Little E<lt>stevan@iinteractive.comE<gt>
320
321=head1 COPYRIGHT AND LICENSE
322
323Copyright 2006 by Infinity Interactive, Inc.
324
325L<http://www.iinteractive.com>
326
327This library is free software; you can redistribute it and/or modify
328it under the same terms as Perl itself.
329
84ef30d1 330=cut
5582521c 331