in Moose::Object add support for a hook BUILDCLASS which allows
[gitmo/Moose.git] / lib / Moose / Object.pm
CommitLineData
fcd84ca9 1
2package Moose::Object;
3
4use strict;
5use warnings;
648e79ae 6
ae736ff4 7use Devel::GlobalDestruction qw(in_global_destruction);
61c4a4cd 8use MRO::Compat;
9use Scalar::Util;
2eaf25da 10
9922fa6f 11use if ( not our $__mx_is_compiled ), 'Moose::Meta::Class';
12use if ( not our $__mx_is_compiled ), metaclass => 'Moose::Meta::Class';
bc1e29b5 13
6fdf3dfa 14our $VERSION = '0.88';
e606ae5f 15$VERSION = eval $VERSION;
d44714be 16our $AUTHORITY = 'cpan:STEVAN';
fcd84ca9 17
18sub new {
2c0cbef7 19 my $class = shift;
2eaf25da 20
e606ae5f 21 my $params = $class->BUILDARGS(@_);
2eaf25da 22
23 # We want to support passing $self->new, but initialize
24 # takes only an unblessed class name
25 my $real_class = Scalar::Util::blessed($class) || $class;
caefeda2 26
27 # this provides a hook to allow subclasses, roles, traits etc a chance to change
28 # how the class will behave
29 my $built_class = $real_class->BUILDALLCLASS($params);
30
31 my $self = Class::MOP::Class->initialize($built_class)->new_object($params);
2eaf25da 32
e606ae5f 33 $self->BUILDALL($params);
2eaf25da 34
e606ae5f 35 return $self;
36}
37
38sub BUILDARGS {
39 my $class = shift;
a62dcd43 40 if ( scalar @_ == 1 ) {
41 unless ( defined $_[0] && ref $_[0] eq 'HASH' ) {
46047bea 42 Class::MOP::class_of($class)->throw_error(
a62dcd43 43 "Single parameters to new() must be a HASH ref",
44 data => $_[0] );
86629f93 45 }
a62dcd43 46 return { %{ $_[0] } };
47 }
8a157bab 48 else {
e606ae5f 49 return {@_};
8a157bab 50 }
fcd84ca9 51}
52
c0e30cf5 53sub BUILDALL {
d03bd989 54 # NOTE: we ask Perl if we even
d44714be 55 # need to do this first, to avoid
56 # extra meta level calls
d03bd989 57 return unless $_[0]->can('BUILD');
fb1e11d5 58 my ($self, $params) = @_;
505033d9 59 foreach my $method (reverse Class::MOP::class_of($self)->find_all_methods_by_name('BUILD')) {
b8f014e7 60 $method->{code}->execute($self, $params);
fb1e11d5 61 }
c0e30cf5 62}
63
caefeda2 64
65sub BUILDALLCLASS {
66 # NOTE: we ask Perl if we even
67 # need to do this first, to avoid
68 # extra meta level calls
69 return $_[0] unless $_[0]->can('BUILDCLASS');
70 my ($class, $params) = @_;
71 foreach my $method (reverse Class::MOP::class_of($class)->find_all_methods_by_name('BUILDCLASS')) {
72 $class = $method->{code}->execute($class, $params);
73 }
74 return $class;
75}
76
c0e30cf5 77sub DEMOLISHALL {
8955a780 78 my $self = shift;
d9359278 79 my ($in_global_destruction) = @_;
8955a780 80
81 # NOTE: we ask Perl if we even
cb5c79c9 82 # need to do this first, to avoid
8955a780 83 # extra meta level calls
cb5c79c9 84 return unless $self->can('DEMOLISH');
8955a780 85
2bc1eab6 86 my @isa;
87 if ( my $meta = Class::MOP::class_of($self ) ) {
88 @isa = $meta->linearized_isa;
89 } else {
90 # We cannot count on being able to retrieve a previously made
91 # metaclass, _or_ being able to make a new one during global
92 # destruction. However, we should still be able to use mro at
93 # that time (at least tests suggest so ;)
94 my $class_name = ref $self;
95 @isa = @{ mro::get_linear_isa($class_name) }
96 }
97
98 foreach my $class (@isa) {
c063fc8b 99 no strict 'refs';
100 my $demolish = *{"${class}::DEMOLISH"}{CODE};
101 $self->$demolish($in_global_destruction)
102 if defined $demolish;
3a0c064a 103 }
104}
105
d03bd989 106sub DESTROY {
3a0c064a 107 # if we have an exception here ...
ca0e380d 108 if ($@) {
109 # localize the $@ ...
110 local $@;
3a0c064a 111 # run DEMOLISHALL ourselves, ...
ae736ff4 112 $_[0]->DEMOLISHALL(in_global_destruction);
3a0c064a 113 # and return ...
114 return;
115 }
ca0e380d 116 # otherwise it is normal destruction
ae736ff4 117 $_[0]->DEMOLISHALL(in_global_destruction);
c0e30cf5 118}
119
e606ae5f 120# support for UNIVERSAL::DOES ...
121BEGIN {
122 my $does = UNIVERSAL->can("DOES") ? "SUPER::DOES" : "isa";
123 eval 'sub DOES {
124 my ( $self, $class_or_role_name ) = @_;
125 return $self->'.$does.'($class_or_role_name)
126 || $self->does($class_or_role_name);
127 }';
128}
129
d03bd989 130# new does() methods will be created
50bc108b 131# as appropiate see Moose::Meta::Role
0677220d 132sub does {
bdabd620 133 my ($self, $role_name) = @_;
66d33a5c 134 my $meta = Class::MOP::class_of($self);
be05faea 135 (defined $role_name)
136 || $meta->throw_error("You much supply a role name to does()");
bdabd620 137 foreach my $class ($meta->class_precedence_list) {
587e457d 138 my $m = $meta->initialize($class);
d03bd989 139 return 1
140 if $m->can('does_role') && $m->does_role($role_name);
bdabd620 141 }
d03bd989 142 return 0;
0677220d 143}
ef333f17 144
d03bd989 145sub dump {
f742dfef 146 my $self = shift;
147 require Data::Dumper;
1a386a6c 148 local $Data::Dumper::Maxdepth = shift if @_;
f742dfef 149 Data::Dumper::Dumper $self;
150}
151
fcd84ca9 1521;
153
154__END__
155
156=pod
157
158=head1 NAME
159
e522431d 160Moose::Object - The base object for Moose
fcd84ca9 161
fcd84ca9 162=head1 DESCRIPTION
163
080e3614 164This class is the default base class for all Moose-using classes. When
165you C<use Moose> in this class, your class will inherit from this
166class.
6ba6d68c 167
080e3614 168It provides a default constructor and destructor, which run the
169C<BUILDALL> and C<DEMOLISHALL> methods respectively.
170
171You don't actually I<need> to inherit from this in order to use Moose,
172but it makes it easier to take advantage of all of Moose's features.
6ba6d68c 173
fcd84ca9 174=head1 METHODS
175
176=over 4
177
080e3614 178=item B<< Moose::Object->new(%params) >>
179
180This method calls C<< $class->BUILDARGS(@_) >>, and then creates a new
181instance of the appropriate class. Once the instance is created, it
182calls C<< $instance->BUILDALL($params) >>.
fcd84ca9 183
080e3614 184=item B<< Moose::Object->BUILDARGS(%params) >>
6ba6d68c 185
080e3614 186The default implementation of this method accepts a hash or hash
187reference of named parameters. If it receives a single argument that
188I<isn't> a hash reference it throws an error.
fcd84ca9 189
080e3614 190You can override this method in your class to handle other types of
191options passed to the constructor.
e606ae5f 192
080e3614 193This method should always return a hash reference of named options.
e606ae5f 194
080e3614 195=item B<< $object->BUILDALL($params) >>
e522431d 196
080e3614 197This method will call every C<BUILD> method in the inheritance
198hierarchy, starting with the most distant parent class and ending with
199the object's class.
c0e30cf5 200
080e3614 201The C<BUILD> method will be passed the hash reference returned by
202C<BUILDARGS>.
e522431d 203
080e3614 204=item B<< $object->DEMOLISHALL >>
c0e30cf5 205
080e3614 206This will call every C<DEMOLISH> method in the inheritance hierarchy,
207starting with the object's class and ending with the most distant
c3fdacda 208parent. C<DEMOLISHALL> and C<DEMOLISH> will receive a boolean
209indicating whether or not we are currently in global destruction.
e522431d 210
080e3614 211=item B<< $object->does($role_name) >>
ef333f17 212
080e3614 213This returns true if the object does the given role.
02a0fb52 214
e606ae5f 215=item B<DOES ($class_or_role_name)>
216
080e3614 217This is a a Moose role-aware implementation of L<UNIVERSAL/DOES>.
e606ae5f 218
080e3614 219This is effectively the same as writing:
e606ae5f 220
080e3614 221 $object->does($name) || $object->isa($name)
f742dfef 222
080e3614 223This method will work with Perl 5.8, which did not implement
224C<UNIVERSAL::DOES>.
f742dfef 225
080e3614 226=item B<< $object->dump($maxdepth) >>
f742dfef 227
080e3614 228This is a handy utility for C<Data::Dumper>ing an object. By default,
229the maximum depth is 1, to avoid making a mess.
f742dfef 230
fcd84ca9 231=back
232
233=head1 BUGS
234
d03bd989 235All complex software has bugs lurking in it, and this module is no
fcd84ca9 236exception. If you find a bug please either email me, or add the bug
237to cpan-RT.
238
fcd84ca9 239=head1 AUTHOR
240
241Stevan Little E<lt>stevan@iinteractive.comE<gt>
242
243=head1 COPYRIGHT AND LICENSE
244
2840a3b2 245Copyright 2006-2009 by Infinity Interactive, Inc.
fcd84ca9 246
247L<http://www.iinteractive.com>
248
249This library is free software; you can redistribute it and/or modify
d03bd989 250it under the same terms as Perl itself.
fcd84ca9 251
9922fa6f 252=cut