2 package Class::MOP::Instance;
7 use Scalar::Util 'weaken', 'blessed';
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
31 slots => { map { $_ => undef } @slots },
37 $self->bless_instance_structure({});
40 sub bless_instance_structure {
41 my ($self, $instance_structure) = @_;
42 bless $instance_structure, $self->{meta}->name;
46 my ($self, $instance) = @_;
47 $self->bless_instance_structure({ %$instance });
50 # operations on meta instance
54 return keys %{$self->{slots}};
58 my ($self, $slot_name) = @_;
59 exists $self->{slots}->{$slot_name} ? 1 : 0;
62 # operations on created instances
65 my ($self, $instance, $slot_name) = @_;
66 return $instance->{$slot_name};
70 my ($self, $instance, $slot_name, $value) = @_;
71 $instance->{$slot_name} = $value;
75 my ($self, $instance, $slot_name) = @_;
76 $self->set_slot_value($instance, $slot_name, undef);
79 sub initialize_all_slots {
80 my ($self, $instance) = @_;
81 foreach my $slot_name ($self->get_all_slots) {
82 $self->initialize_slot($instance, $slot_name);
86 sub is_slot_initialized {
87 my ($self, $instance, $slot_name, $value) = @_;
88 exists $instance->{$slot_name} ? 1 : 0;
91 sub weaken_slot_value {
92 my ($self, $instance, $slot_name) = @_;
93 weaken $instance->{$slot_name};
96 sub strengthen_slot_value {
97 my ($self, $instance, $slot_name) = @_;
98 $self->set_slot_value($instance, $slot_name, $self->get_slot_value($instance, $slot_name));
101 # inlinable operation snippets
103 sub is_inlinable { 1 }
105 sub inline_create_instance {
106 my ($self, $class_variable) = @_;
107 'bless {} => ' . $class_variable;
110 sub inline_slot_access {
111 my ($self, $instance, $slot_name) = @_;
112 sprintf "%s->{%s}", $instance, $slot_name;
115 sub inline_get_slot_value {
116 my ($self, $instance, $slot_name) = @_;
117 $self->inline_slot_access($instance, $slot_name);
120 sub inline_set_slot_value {
121 my ($self, $instance, $slot_name, $value) = @_;
122 $self->inline_slot_access($instance, $slot_name) . " = $value",
125 sub inline_initialize_slot {
126 my ($self, $instance, $slot_name) = @_;
127 $self->inline_set_slot_value($instance, $slot_name, 'undef'),
130 sub inline_is_slot_initialized {
131 my ($self, $instance, $slot_name) = @_;
132 "exists " . $self->inline_slot_access($instance, $slot_name) . " ? 1 : 0";
135 sub inline_weaken_slot_value {
136 my ($self, $instance, $slot_name) = @_;
137 sprintf "Scalar::Util::weaken( %s )", $self->inline_slot_access($instance, $slot_name);
140 sub 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));
153 Class::MOP::Instance - Instance Meta Object
157 # for the most part, this protocol is internal
158 # and not for public usage, but this how one
166 ':instance_metaclass' => 'ArrayBasedStorage::Instance',
169 # now Foo->new produces blessed ARRAY ref based objects
173 This is a sub-protocol which governs instance creation
174 and access to the slots of the instance structure.
176 This may seem like over-abstraction, but by abstracting
177 this process into a sub-protocol we make it possible to
178 easily switch the details of how an object's instance is
179 stored with minimal impact. In most cases just subclassing
180 this class will be all you need to do (see the examples;
181 F<examples/ArrayBasedStorage.pod> and
182 F<examples/InsideOutClass.pod> for details).
188 =item B<new ($meta, @attrs)>
190 Creates a new instance meta-object and gathers all the slots from
191 the list of C<@attrs> given.
195 This will return a B<Class::MOP::Class> instance which is related
200 =head2 Creation of Instances
204 =item B<create_instance>
206 This creates the appropriate structure needed for the instance and
207 then calls C<bless_instance_structure> to bless it into the class.
209 =item B<bless_instance_structure ($instance_structure)>
211 This does just exactly what it says it does.
213 =item B<clone_instance ($instance_structure)>
217 =head2 Instrospection
219 NOTE: There might be more methods added to this part of the API,
220 we will add then when we need them basically.
224 =item B<get_all_slots>
226 This will return the current list of slots based on what was
227 given to this object in C<new>.
229 =item B<is_valid_slot ($slot_name)>
233 =head2 Operations on Instance Structures
235 An important distinction of this sub-protocol is that the
236 instance meta-object is a different entity from the actual
237 instance it creates. For this reason, any actions on slots
238 require that the C<$instance_structure> is passed into them.
242 =item B<get_slot_value ($instance_structure, $slot_name)>
244 =item B<set_slot_value ($instance_structure, $slot_name, $value)>
246 =item B<initialize_slot ($instance_structure, $slot_name)>
248 =item B<initialize_all_slots ($instance_structure)>
250 =item B<is_slot_initialized ($instance_structure, $slot_name)>
252 =item B<weaken_slot_value ($instance_structure, $slot_name)>
254 =item B<strengthen_slot_value ($instance_structure, $slot_name)>
258 =head2 Inlineable Instance Operations
260 This part of the API is currently un-used. It is there for use
261 in future experiments in class finailization mostly. Best to
266 =item B<is_inlinable>
268 Each meta-instance should override this method to tell Class::MOP if it's
269 possible to inline the slot access.
271 This is currently only used by Class::MOP::Class::Immutable when performing
274 =item B<inline_create_instance>
276 =item B<inline_slot_access ($instance_structure, $slot_name)>
278 =item B<inline_get_slot_value ($instance_structure, $slot_name)>
280 =item B<inline_set_slot_value ($instance_structure, $slot_name, $value)>
282 =item B<inline_initialize_slot ($instance_structure, $slot_name)>
284 =item B<inline_is_slot_initialized ($instance_structure, $slot_name)>
286 =item B<inline_weaken_slot_value ($instance_structure, $slot_name)>
288 =item B<inline_strengthen_slot_value ($instance_structure, $slot_name)>
294 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
296 Stevan Little E<lt>stevan@iinteractive.comE<gt>
298 =head1 COPYRIGHT AND LICENSE
300 Copyright 2006 by Infinity Interactive, Inc.
302 L<http://www.iinteractive.com>
304 This library is free software; you can redistribute it and/or modify
305 it under the same terms as Perl itself.