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