bunch of doc fixes
[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
0c6f4c4a 9our $VERSION = '0.04';
f0480c45 10our $AUTHORITY = 'cpan:STEVAN';
24869f62 11
8d2d4c67 12sub meta {
24869f62 13 require Class::MOP::Class;
14 Class::MOP::Class->initialize(blessed($_[0]) || $_[0]);
15}
16
8d2d4c67 17sub new {
052c2a1a 18 my ($class, $meta, @attrs) = @_;
c57c8b10 19 my @slots = map { $_->slots } @attrs;
c23184fc 20 my $instance = bless {
fc3ddd1d 21 # NOTE:
22 # I am not sure that it makes
23 # sense to pass in the meta
8d2d4c67 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(),
fc3ddd1d 28 # which is *probably* a safe
8d2d4c67 29 # assumption,.. but you can
fc3ddd1d 30 # never tell <:)
c23184fc 31 '$!meta' => $meta,
32 '@!slots' => { map { $_ => undef } @slots },
8d2d4c67 33 } => $class;
34
c23184fc 35 weaken($instance->{'$!meta'});
8d2d4c67 36
c23184fc 37 return $instance;
24869f62 38}
39
c23184fc 40sub associated_metaclass { (shift)->{'$!meta'} }
41
49c93440 42sub create_instance {
43 my $self = shift;
44 $self->bless_instance_structure({});
2d711cc8 45}
46
49c93440 47sub bless_instance_structure {
48 my ($self, $instance_structure) = @_;
c23184fc 49 bless $instance_structure, $self->associated_metaclass->name;
2d711cc8 50}
51
f7259199 52sub clone_instance {
53 my ($self, $instance) = @_;
54 $self->bless_instance_structure({ %$instance });
55}
56
2d711cc8 57# operations on meta instance
58
eb49acde 59sub get_all_slots {
60 my $self = shift;
c23184fc 61 return keys %{$self->{'@!slots'}};
f7259199 62}
63
64sub is_valid_slot {
65 my ($self, $slot_name) = @_;
230472a7 66 exists $self->{'@!slots'}->{$slot_name};
839ea973 67}
68
2d711cc8 69# operations on created instances
70
839ea973 71sub get_slot_value {
2bab2be6 72 my ($self, $instance, $slot_name) = @_;
230472a7 73 $instance->{$slot_name};
839ea973 74}
75
2bab2be6 76sub set_slot_value {
77 my ($self, $instance, $slot_name, $value) = @_;
78 $instance->{$slot_name} = $value;
79}
80
2d711cc8 81sub initialize_slot {
49c93440 82 my ($self, $instance, $slot_name) = @_;
8d2d4c67 83 #$self->set_slot_value($instance, $slot_name, undef);
2d711cc8 84}
85
7d28758b 86sub deinitialize_slot {
87 my ( $self, $instance, $slot_name ) = @_;
88 delete $instance->{$slot_name};
89}
90
c174112e 91sub initialize_all_slots {
92 my ($self, $instance) = @_;
93 foreach my $slot_name ($self->get_all_slots) {
94 $self->initialize_slot($instance, $slot_name);
95 }
96}
97
7d28758b 98sub deinitialize_all_slots {
99 my ($self, $instance) = @_;
100 foreach my $slot_name ($self->get_all_slots) {
101 $self->deinitialize_slot($instance, $slot_name);
102 }
103}
104
49c93440 105sub is_slot_initialized {
106 my ($self, $instance, $slot_name, $value) = @_;
230472a7 107 exists $instance->{$slot_name};
2bab2be6 108}
839ea973 109
5582521c 110sub weaken_slot_value {
69e3ab0a 111 my ($self, $instance, $slot_name) = @_;
112 weaken $instance->{$slot_name};
5582521c 113}
114
115sub strengthen_slot_value {
69e3ab0a 116 my ($self, $instance, $slot_name) = @_;
117 $self->set_slot_value($instance, $slot_name, $self->get_slot_value($instance, $slot_name));
5582521c 118}
119
3d9e4646 120sub rebless_instance_structure {
121 my ($self, $instance, $metaclass) = @_;
122 bless $instance, $metaclass->name;
123}
124
ee7c0467 125# inlinable operation snippets
126
c0cbf4d9 127sub is_inlinable { 1 }
128
129sub inline_create_instance {
130 my ($self, $class_variable) = @_;
131 'bless {} => ' . $class_variable;
132}
133
ee7c0467 134sub inline_slot_access {
135 my ($self, $instance, $slot_name) = @_;
136 sprintf "%s->{%s}", $instance, $slot_name;
137}
138
139sub inline_get_slot_value {
140 my ($self, $instance, $slot_name) = @_;
230472a7 141 $self->inline_slot_access($instance, $slot_name);
ee7c0467 142}
143
144sub inline_set_slot_value {
145 my ($self, $instance, $slot_name, $value) = @_;
8d2d4c67 146 $self->inline_slot_access($instance, $slot_name) . " = $value",
ee7c0467 147}
148
149sub inline_initialize_slot {
150 my ($self, $instance, $slot_name) = @_;
151 $self->inline_set_slot_value($instance, $slot_name, 'undef'),
152}
153
7d28758b 154sub inline_deinitialize_slot {
155 my ($self, $instance, $slot_name) = @_;
156 "delete " . $self->inline_slot_access($instance, $slot_name);
157}
ee7c0467 158sub inline_is_slot_initialized {
159 my ($self, $instance, $slot_name) = @_;
230472a7 160 "exists " . $self->inline_slot_access($instance, $slot_name);
ee7c0467 161}
162
163sub inline_weaken_slot_value {
164 my ($self, $instance, $slot_name) = @_;
165 sprintf "Scalar::Util::weaken( %s )", $self->inline_slot_access($instance, $slot_name);
166}
167
168sub inline_strengthen_slot_value {
169 my ($self, $instance, $slot_name) = @_;
170 $self->inline_set_slot_value($instance, $slot_name, $self->inline_slot_access($instance, $slot_name));
171}
172
24869f62 1731;
174
175__END__
176
177=pod
178
8d2d4c67 179=head1 NAME
24869f62 180
181Class::MOP::Instance - Instance Meta Object
182
24869f62 183=head1 DESCRIPTION
184
bc9e7815 185The meta instance is used by attributes for low level storage.
186
187Using this API generally violates attribute encapsulation and is not
188reccomended, instead look at L<Class::MOP::Attribute/get_value>,
189L<Class::MOP::Attribute/set_value> for the reccomended way to fiddle with
190attribute values in a generic way, independant of how/whether accessors have
191been defined. Accessors can be found using L<Class::MOP::Class/get_attribute>.
9fa4d0b4 192
8d2d4c67 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
197this class will be all you need to do (see the examples;
198F<examples/ArrayBasedStorage.pod> and
1becdfcc 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
8d2d4c67 207Creates a new instance meta-object and gathers all the slots from
9fa4d0b4 208the list of C<@attrs> given.
209
210=item B<meta>
211
8d2d4c67 212This will return a B<Class::MOP::Class> instance which is related
9fa4d0b4 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
8d2d4c67 223This creates the appropriate structure needed for the instance and
9fa4d0b4 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
127d39a7 232This too does just exactly what it says it does.
233
9fa4d0b4 234=back
839ea973 235
9fa4d0b4 236=head2 Instrospection
58287a97 237
8d2d4c67 238NOTE: There might be more methods added to this part of the API,
9fa4d0b4 239we will add then when we need them basically.
58287a97 240
9fa4d0b4 241=over 4
242
c23184fc 243=item B<associated_metaclass>
244
127d39a7 245This returns the metaclass associated with this instance.
246
9fa4d0b4 247=item B<get_all_slots>
248
8d2d4c67 249This will return the current list of slots based on what was
9fa4d0b4 250given to this object in C<new>.
58287a97 251
f7259199 252=item B<is_valid_slot ($slot_name)>
253
127d39a7 254This will return true if C<$slot_name> is a valid slot name.
255
24869f62 256=back
257
9fa4d0b4 258=head2 Operations on Instance Structures
259
8d2d4c67 260An important distinction of this sub-protocol is that the
261instance meta-object is a different entity from the actual
262instance it creates. For this reason, any actions on slots
9fa4d0b4 263require that the C<$instance_structure> is passed into them.
24869f62 264
127d39a7 265The names of these methods pretty much explain exactly
266what they do, if that is not enough then I suggest reading
267the source, it is very straightfoward.
268
24869f62 269=over 4
270
9fa4d0b4 271=item B<get_slot_value ($instance_structure, $slot_name)>
24869f62 272
9fa4d0b4 273=item B<set_slot_value ($instance_structure, $slot_name, $value)>
274
275=item B<initialize_slot ($instance_structure, $slot_name)>
276
7d28758b 277=item B<deinitialize_slot ($instance_structure, $slot_name)>
278
9fa4d0b4 279=item B<initialize_all_slots ($instance_structure)>
280
7d28758b 281=item B<deinitialize_all_slots ($instance_structure)>
282
9fa4d0b4 283=item B<is_slot_initialized ($instance_structure, $slot_name)>
24869f62 284
ee7c0467 285=item B<weaken_slot_value ($instance_structure, $slot_name)>
286
287=item B<strengthen_slot_value ($instance_structure, $slot_name)>
288
5fdf066d 289=item B<rebless_instance_structure ($instance_structure, $new_metaclass)>
290
ee7c0467 291=back
292
293=head2 Inlineable Instance Operations
294
295=over 4
296
c0cbf4d9 297=item B<is_inlinable>
298
8d2d4c67 299Each meta-instance should override this method to tell Class::MOP if it's
127d39a7 300possible to inline the slot access. This is currently only used by
301L<Class::MOP::Immutable> when performing optimizations.
c0cbf4d9 302
495af518 303=item B<inline_create_instance>
304
ee7c0467 305=item B<inline_slot_access ($instance_structure, $slot_name)>
306
307=item B<inline_get_slot_value ($instance_structure, $slot_name)>
308
309=item B<inline_set_slot_value ($instance_structure, $slot_name, $value)>
310
311=item B<inline_initialize_slot ($instance_structure, $slot_name)>
312
7d28758b 313=item B<inline_deinitialize_slot ($instance_structure, $slot_name)>
314
ee7c0467 315=item B<inline_is_slot_initialized ($instance_structure, $slot_name)>
5582521c 316
ee7c0467 317=item B<inline_weaken_slot_value ($instance_structure, $slot_name)>
5582521c 318
ee7c0467 319=item B<inline_strengthen_slot_value ($instance_structure, $slot_name)>
5582521c 320
24869f62 321=back
322
1a09d9cc 323=head1 AUTHORS
24869f62 324
9fa4d0b4 325Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
326
24869f62 327Stevan Little E<lt>stevan@iinteractive.comE<gt>
328
329=head1 COPYRIGHT AND LICENSE
330
69e3ab0a 331Copyright 2006-2008 by Infinity Interactive, Inc.
24869f62 332
333L<http://www.iinteractive.com>
334
335This library is free software; you can redistribute it and/or modify
8d2d4c67 336it under the same terms as Perl itself.
24869f62 337
84ef30d1 338=cut
5582521c 339