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