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