2 package Class::MOP::Instance;
7 use Scalar::Util 'weaken';
12 require Class::MOP::Class;
13 Class::MOP::Class->initialize(blessed($_[0]) || $_[0]);
17 my ($class, $meta, @attrs) = @_;
18 my @slots = map { $_->slots } @attrs;
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
37 $self->bless_instance_structure({});
40 sub bless_instance_structure {
41 my ($self, $instance_structure) = @_;
42 bless $instance_structure, $self->{meta}->name;
45 # operations on meta instance
49 return @{$self->{slots}};
52 # operations on created instances
55 my ($self, $instance, $slot_name) = @_;
56 return $instance->{$slot_name};
60 my ($self, $instance, $slot_name, $value) = @_;
61 $instance->{$slot_name} = $value;
65 my ($self, $instance, $slot_name) = @_;
66 $instance->{$slot_name} = undef;
69 sub initialize_all_slots {
70 my ($self, $instance) = @_;
71 foreach my $slot_name ($self->get_all_slots) {
72 $self->initialize_slot($instance, $slot_name);
76 sub is_slot_initialized {
77 my ($self, $instance, $slot_name, $value) = @_;
78 exists $instance->{$slot_name} ? 1 : 0;
81 sub weaken_slot_value {
82 my ($self, $instance, $slot_name) = @_;
83 weaken $instance->{$slot_name};
86 sub strengthen_slot_value {
87 my ($self, $instance, $slot_name) = @_;
88 $self->set_slot_value($instance, $slot_name, $self->get_slot_value($instance, $slot_name));
91 # inlinable operation snippets
93 sub inline_slot_access {
94 my ($self, $instance, $slot_name) = @_;
95 sprintf "%s->{%s}", $instance, $slot_name;
98 sub inline_get_slot_value {
99 my ($self, $instance, $slot_name) = @_;
100 $self->inline_slot_access($instance, $slot_name);
103 sub inline_set_slot_value {
104 my ($self, $instance, $slot_name, $value) = @_;
105 $self->inline_slot_access($instance, $slot_name) . " = $value",
108 sub inline_initialize_slot {
109 my ($self, $instance, $slot_name) = @_;
110 $self->inline_set_slot_value($instance, $slot_name, 'undef'),
113 sub inline_is_slot_initialized {
114 my ($self, $instance, $slot_name) = @_;
115 "exists " . $self->inline_slot_access($instance, $slot_name) . " ? 1 : 0";
118 sub inline_weaken_slot_value {
119 my ($self, $instance, $slot_name) = @_;
120 sprintf "Scalar::Util::weaken( %s )", $self->inline_slot_access($instance, $slot_name);
123 sub inline_strengthen_slot_value {
124 my ($self, $instance, $slot_name) = @_;
125 $self->inline_set_slot_value($instance, $slot_name, $self->inline_slot_access($instance, $slot_name));
136 Class::MOP::Instance - Instance Meta Object
140 # for the most part, this protocol is internal
141 # and not for public usage, but this how one
149 ':instance_metaclass' => 'ArrayBasedStorage::Instance',
152 # now Foo->new produces blessed ARRAY ref based objects
156 This is a sub-protocol which governs instance creation
157 and access to the slots of the instance structure.
159 This may seem like over-abstraction, but by abstracting
160 this process into a sub-protocol we make it possible to
161 easily switch the details of how an object's instance is
162 stored with minimal impact. In most cases just subclassing
163 this class will be all you need to do (see the examples;
164 F<examples/ArrayBasedStorage.pod> and
165 F<examples/InsideOutClass.pod> for details).
171 =item B<new ($meta, @attrs)>
173 Creates a new instance meta-object and gathers all the slots from
174 the list of C<@attrs> given.
178 This will return a B<Class::MOP::Class> instance which is related
183 =head2 Creation of Instances
187 =item B<create_instance>
189 This creates the appropriate structure needed for the instance and
190 then calls C<bless_instance_structure> to bless it into the class.
192 =item B<bless_instance_structure ($instance_structure)>
194 This does just exactly what it says it does.
198 =head2 Instrospection
200 NOTE: There might be more methods added to this part of the API,
201 we will add then when we need them basically.
205 =item B<get_all_slots>
207 This will return the current list of slots based on what was
208 given to this object in C<new>.
212 =head2 Operations on Instance Structures
214 An important distinction of this sub-protocol is that the
215 instance meta-object is a different entity from the actual
216 instance it creates. For this reason, any actions on slots
217 require that the C<$instance_structure> is passed into them.
221 =item B<get_slot_value ($instance_structure, $slot_name)>
223 =item B<set_slot_value ($instance_structure, $slot_name, $value)>
225 =item B<initialize_slot ($instance_structure, $slot_name)>
227 =item B<initialize_all_slots ($instance_structure)>
229 =item B<is_slot_initialized ($instance_structure, $slot_name)>
231 =item B<weaken_slot_value ($instance_structure, $slot_name)>
233 =item B<strengthen_slot_value ($instance_structure, $slot_name)>
237 =head2 Inlineable Instance Operations
241 =item B<inline_slot_access ($instance_structure, $slot_name)>
243 =item B<inline_get_slot_value ($instance_structure, $slot_name)>
245 =item B<inline_set_slot_value ($instance_structure, $slot_name, $value)>
247 =item B<inline_initialize_slot ($instance_structure, $slot_name)>
249 =item B<inline_is_slot_initialized ($instance_structure, $slot_name)>
251 =item B<inline_weaken_slot_value ($instance_structure, $slot_name)>
253 =item B<inline_strengthen_slot_value ($instance_structure, $slot_name)>
259 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
261 Stevan Little E<lt>stevan@iinteractive.comE<gt>
263 =head1 COPYRIGHT AND LICENSE
265 Copyright 2006 by Infinity Interactive, Inc.
267 L<http://www.iinteractive.com>
269 This library is free software; you can redistribute it and/or modify
270 it under the same terms as Perl itself.