2 package Class::MOP::Instance;
8 use Scalar::Util 'blessed', 'reftype', 'weaken';
10 our $VERSION = '0.01';
13 require Class::MOP::Class;
14 Class::MOP::Class->initialize(blessed($_[0]) || $_[0]);
18 my ( $class, $meta ) = @_;
26 my ( $self, $class ) = @_;
28 # rely on autovivification
29 $self->bless_instance_structure( {}, $class );
32 sub bless_instance_structure {
33 my ( $self, $instance_structure, $class ) = @_;
34 $class ||= $self->{meta}->name;
35 bless $instance_structure, $class;
40 my @parents = $self->{meta}->class_precedence_list;
41 shift @parents; # shift off ourselves
42 return map { $_->get_meta_instance } map { $_->meta || () } @parents;
45 # operations on meta instance
48 my ($self, $slot_name ) = @_;
49 confess "The slot '$slot_name' already exists"
50 if 0 && $self->has_slot_recursively( $slot_name ); # FIXME
51 $self->{instance_layout}->{$slot_name} = undef;
56 keys %{ $self->{instance_layout} };
59 sub get_all_slots_recursively {
63 map { $_->get_all_slots } $self->get_all_parents,
68 my ($self, $slot_name) = @_;
69 exists $self->{instance_layout}->{$slot_name} ? 1 : 0;
72 sub has_slot_recursively {
73 my ( $self, $slot_name ) = @_;
74 return 1 if $self->has_slot($slot_name);
75 $_->has_slot_recursively($slot_name) && return 1 for $self->get_all_parents;
80 my ( $self, $slot_name ) = @_;
82 # this does not search recursively cause
83 # that is not the domain of this meta-instance
84 # it is specific to this class ...
85 confess "The slot '$slot_name' does not exist (maybe it's inherited?)"
86 if 0 && $self->has_slot( $slot_name ); # FIXME
87 delete $self->{instance_layout}->{$slot_name};
91 # operations on created instances
94 my ($self, $instance, $slot_name) = @_;
95 return $instance->{$slot_name};
98 # can be called only after initialize_slot_value
100 my ($self, $instance, $slot_name, $value) = @_;
101 $instance->{$slot_name} = $value;
104 sub set_weak_slot_value {
105 my ( $self, $instance, $slot_name, $value) = @_;
106 $self->set_slot_value( $instance, $slot_name, $value );
107 $self->weeaken_slot_value( $instance, $slot_name );
110 sub weaken_slot_value {
111 my ( $self, $instance, $slot_name ) = @_;
112 weaken( $instance->{$slot_name} );
116 # non autovivifying stores will have this as { initialize_slot unless slot_initlized; set_slot_value }
117 sub set_slot_value_with_init {
118 my ( $self, $instance, $slot_name, $value ) = @_;
119 $self->set_slot_value( $instance, $slot_name, $value );
122 sub initialize_slot {
123 my ( $self, $instance, $slot_name ) = @_;
126 sub slot_initialized {
127 my ($self, $instance, $slot_name) = @_;
128 exists $instance->{$slot_name} ? 1 : 0;
132 # inlinable operation snippets
134 sub inline_get_slot_value {
135 my ($self, $instance, $slot_name) = @_;
136 sprintf "%s->{%s}", $instance, $slot_name;
139 sub inline_set_slot_value {
140 my ($self, $instance, $slot_name, $value) = @_;
141 $self->_inline_slot_lvalue( $instance, $slot_name ) . " = $value",
144 sub inline_set_weak_slot_value {
145 my ( $self, $instance, $slot_name, $value ) = @_;
147 . $self->inline_set_slot_value( $instance, $slot_name, $value )
149 . $self->inline_weaken_slot_value( $instance, $slot_name );
152 sub inline_weaken_slot_value {
153 my ( $self, $instance, $slot_name ) = @_;
154 return 'Scalar::Util::weaken( ' . $self->_inline_slot_lvalue( $instance, $slot_name ) . ')';
157 sub inline_set_slot_value_with_init {
158 my ( $self, $instance, $slot_name, $value) = @_;
159 $self->inline_set_slot_value( $instance, $slot_name, $value ) . ";";
162 sub inline_initialize_slot {
166 sub inline_slot_initialized {
167 my ($self, $instance, $slot_name) = @_;
168 "exists " . $self->inline_get_slot_value;
171 sub _inline_slot_lvalue {
172 my ($self, $instance, $slot_name) = @_;
173 $self->inline_get_slot_value( $instance, $slot_name );
184 Class::MOP::Instance - Instance Meta Object
198 =item B<bless_instance_structure>
200 =item B<create_instance>
202 =item B<get_all_parents>
204 =item B<get_slot_value>
208 =item B<has_slot_recursively>
210 =item B<initialize_slot>
212 =item B<inline_get_slot_value>
214 =item B<inline_initialize_slot>
216 =item B<inline_set_slot_value>
218 =item B<inline_set_slot_value_with_init>
220 =item B<inline_slot_initialized>
224 =item B<set_slot_value>
226 =item B<set_slot_value_with_init>
228 =item B<slot_initialized>
230 =item B<get_all_slots>
232 =item B<get_all_slots_recursively>
242 This will return a B<Class::MOP::Class> instance which is related
249 Stevan Little E<lt>stevan@iinteractive.comE<gt>
251 =head1 COPYRIGHT AND LICENSE
253 Copyright 2006 by Infinity Interactive, Inc.
255 L<http://www.iinteractive.com>
257 This library is free software; you can redistribute it and/or modify
258 it under the same terms as Perl itself.