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