2 package # hide the package from PAUSE
3 InsideOutClass::Attribute;
10 our $VERSION = '0.01';
12 use base 'Class::MOP::Attribute';
14 sub generate_accessor_method {
16 my $attr_name = $self->name;
18 my $meta_instance = $_[0]->meta->get_meta_instance;
19 $meta_instance->set_slot_value($_[0], $attr_name, $_[1]) if scalar(@_) == 2;
20 $meta_instance->get_slot_value($_[0], $attr_name);
24 sub generate_reader_method {
26 my $attr_name = $self->name;
28 confess "Cannot assign a value to a read-only accessor" if @_ > 1;
31 ->get_slot_value($_[0], $attr_name);
35 sub generate_writer_method {
37 my $attr_name = $self->name;
41 ->set_slot_value($_[0], $attr_name, $_[1]);
45 sub generate_predicate_method {
47 my $attr_name = $self->name;
51 ->get_slot_value($_[0], $attr_name) ? 1 : 0;
55 package # hide the package from PAUSE
56 InsideOutClass::Instance;
61 our $VERSION = '0.06';
64 use Scalar::Util 'refaddr';
66 use base 'Class::MOP::Instance';
69 my ($self, $class) = @_;
70 $self->bless_instance_structure(\(my $instance));
74 my ($self, $instance, $slot_name) = @_;
75 $self->{meta}->get_package_variable('%' . $slot_name)->{refaddr $instance};
79 my ($self, $instance, $slot_name, $value) = @_;
80 $self->{meta}->get_package_variable('%' . $slot_name)->{refaddr $instance} = $value;
84 my ($self, $instance, $slot_name) = @_;
85 $self->{meta}->add_package_variable(('%' . $slot_name) => {})
86 unless $self->{meta}->has_package_variable('%' . $slot_name);
87 $self->{meta}->get_package_variable('%' . $slot_name)->{refaddr $instance} = undef;
90 sub is_slot_initialized {
91 my ($self, $instance, $slot_name) = @_;
92 return 0 unless $self->{meta}->has_package_variable('%' . $slot_name);
93 return exists $self->{meta}->get_package_variable('%' . $slot_name)->{refaddr $instance} ? 1 : 0;
104 InsideOutClass - A set of example metaclasses which implement the Inside-Out technique
110 use metaclass 'Class::MOP::Class' => (
111 # tell our metaclass to use the
112 # InsideOut attribute metclass
113 # to construct all it's attributes
114 ':instance_metaclass' => 'InsideOutClass::Instance'
117 __PACKAGE__->meta->add_attribute('foo' => (
124 $class->meta->new_object(@_);
127 # now you can just use the class as normal
131 This is a set of example metaclasses which implement the Inside-Out
132 class technique. What follows is a brief explaination of the code
133 found in this module.
135 We must create a subclass of B<Class::MOP::Instance> and override
136 the slot operations. This requires
137 overloading C<get_slot_value>, C<set_slot_value>, C<slot_initialized>, and
138 C<initialize_slot>, as well as their inline counterparts. Additionally we
139 overload C<add_slot> in order to initialize the global hash containing the
142 And that is pretty much all. Of course I am ignoring need for
143 inside-out objects to be C<DESTROY>-ed, and some other details as
144 well (threading, etc), but this is an example. A real implementation is left as
145 an exercise to the reader.
149 Stevan Little E<lt>stevan@iinteractive.comE<gt>
153 L<Tie::RefHash::Weak>
155 =head1 COPYRIGHT AND LICENSE
157 Copyright 2006 by Infinity Interactive, Inc.
159 L<http://www.iinteractive.com>
161 This library is free software; you can redistribute it and/or modify
162 it under the same terms as Perl itself.