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