The great Class::MOP::Instance refactoring
[gitmo/Class-MOP.git] / examples / LazyClass.pod
CommitLineData
4300f56a 1
046688ed 2package # hide the package from PAUSE
046688ed 3 LazyClass::Attribute;
4300f56a 4
5use strict;
6use warnings;
7
b9dfbf78 8use Carp 'confess';
9
2bab2be6 10our $VERSION = '0.04';
4300f56a 11
12use base 'Class::MOP::Attribute';
13
fed4cee7 14sub initialize_instance_slot {
2d711cc8 15 my ($self, $instance, $params) = @_;
16
fed4cee7 17 # if the attr has an init_arg, use that, otherwise,
18 # use the attributes name itself as the init_arg
19 my $init_arg = $self->init_arg();
fed4cee7 20
2d711cc8 21 if ( exists $params->{$init_arg} ) {
22 my $val = $params->{$init_arg};
23 my $meta_instance = $self->associated_class->get_meta_instance;
24 $meta_instance->set_slot_value_with_init( $instance, $self->slot_name, $val);
25 }
26}
fed4cee7 27
4300f56a 28sub generate_accessor_method {
2d711cc8 29 my $attr = shift;
30
31 my $slot_name = $attr->slot_name;
32 my $meta_instance = $attr->associated_class->get_meta_instance;
33
4300f56a 34 sub {
35 if (scalar(@_) == 2) {
2d711cc8 36 $meta_instance->set_slot_value_with_init( $_[0], $slot_name, $_[1] );
4300f56a 37 }
38 else {
2d711cc8 39 unless ( $meta_instance->slot_initialized( $_[0], $slot_name ) ) {
40 my $value = $attr->has_default ? $attr->default($_[0]) : undef;
41 $meta_instance->set_slot_value_with_init( $_[0], $slot_name, $value );
42 }
43
44 $meta_instance->get_slot_value( $_[0], $slot_name );
4300f56a 45 }
46 };
47}
48
49sub generate_reader_method {
2d711cc8 50 my $attr = shift;
51
52 my $slot_name = $attr->slot_name;
53 my $meta_instance = $attr->associated_class->get_meta_instance;
54
4300f56a 55 sub {
b9dfbf78 56 confess "Cannot assign a value to a read-only accessor" if @_ > 1;
2d711cc8 57
58 unless ( $meta_instance->slot_initialized( $_[0], $slot_name ) ) {
59 my $value = $attr->has_default ? $attr->default($_[0]) : undef;
60 $meta_instance->set_slot_value_with_init( $_[0], $slot_name, $value );
61 }
62
63 $meta_instance->get_slot_value( $_[0], $slot_name );
4300f56a 64 };
65}
66
671;
68
69__END__
70
71=pod
72
73=head1 NAME
74
75LazyClass - An example metaclass with lazy initialization
76
77=head1 SYNOPSIS
78
79 package BinaryTree;
80
fed4cee7 81 use metaclass 'Class::MOP::Class' => (
677eb158 82 ':attribute_metaclass' => 'LazyClass::Attribute'
83 );
4300f56a 84
85 BinaryTree->meta->add_attribute('$:node' => (
86 accessor => 'node',
87 init_arg => ':node'
88 ));
89
90 BinaryTree->meta->add_attribute('$:left' => (
91 reader => 'left',
92 default => sub { BinaryTree->new() }
93 ));
94
95 BinaryTree->meta->add_attribute('$:right' => (
96 reader => 'right',
97 default => sub { BinaryTree->new() }
98 ));
99
5659d76e 100 sub new {
4300f56a 101 my $class = shift;
5659d76e 102 $class->meta->new_object(@_);
4300f56a 103 }
104
105 # ... later in code
106
107 my $btree = BinaryTree->new();
108 # ... $btree is an empty hash, no keys are initialized yet
109
110=head1 DESCRIPTION
111
112This is an example metclass in which all attributes are created
113lazily. This means that no entries are made in the instance HASH
114until the last possible moment.
115
116The example above of a binary tree is a good use for such a
117metaclass because it allows the class to be space efficient
118without complicating the programing of it. This would also be
119ideal for a class which has a large amount of attributes,
120several of which are optional.
121
122=head1 AUTHOR
123
124Stevan Little E<lt>stevan@iinteractive.comE<gt>
125
126=head1 COPYRIGHT AND LICENSE
127
128Copyright 2006 by Infinity Interactive, Inc.
129
130L<http://www.iinteractive.com>
131
132This library is free software; you can redistribute it and/or modify
133it under the same terms as Perl itself.
134
2d711cc8 135=cut