File Coverage

blib/lib/Moos.pm
Criterion Covered Total %
statement 275 354 77.6
branch 105 170 61.7
condition 31 71 43.6
subroutine 58 74 78.3
pod 3 4 75.0
total 472 673 70.1


line stmt bran cond sub pod time code
1             # The entire implementation of Moos (and all its related classes) are defined
2             # inside this one file.
3 9     9   254586 use strict; use warnings;
  9     9   22  
  9         487  
  9         51  
  9         19  
  9         1257  
4              
5             my $VALID_NAME = qr{ ^ [^\W0-9] \w* $ }ix;
6              
7             package Moos;
8              
9             our $VERSION = '0.30';
10              
11 9     9   69 use Scalar::Util;
  9         18  
  9         721  
12 9     9   52 use Carp qw(confess);
  9         52  
  9         1443  
13              
14             if ($] >= 5.010) {
15             require mro;
16             }
17             else {
18             require MRO::Compat;
19             }
20              
21             our $CAN_HAZ_XS =
22             !$ENV{PERL_MOOS_XS_DISABLE} &&
23             eval{ require Class::XSAccessor; Class::XSAccessor->VERSION("1.07"); 1 };
24              
25 9     9   48 use constant default_metaclass => 'Moos::Meta::Class';
  9         21  
  9         1399  
26 9     9   53 use constant default_metarole => 'Moos::Meta::Role';
  9         21  
  9         916  
27 9     9   51 use constant default_base_class => 'Moos::Object';
  9         17  
  9         16744  
28              
29             sub import {
30             # Turn on strict/warnings for caller
31 16     16   7615 strict->import;
32 16         207 warnings->import;
33              
34 16 100 100     147 ($_[1]||'') eq -Role and goto \&role_import;
35              
36 14         33 my ($class, %args) = @_;
37 14         33 my $package = caller;
38              
39             # Create/register a metaclass object for the package
40 14   33     233 my $metaclass =
41             delete $args{metaclass}
42             || $class->default_metaclass;
43 14         64 my $meta = $metaclass->initialize($package, %args);
44              
45             # Make calling class inherit from Moos::Object by default
46 14 50       121 my $baseclass = exists $args{base_class}
47             ? delete $args{base_class}
48             : $class->default_base_class;
49 14 50       69 extends($meta, $baseclass) if defined $baseclass;
50              
51             # Export the 'has', 'extends', and 'with' helper functions
52 14         57 _export($package, has => \&has, $meta);
53 14         41 _export($package, extends => \&extends, $meta);
54 14         41 _export($package, with => \&with, $meta);
55              
56             # Export the 'blessed' and 'confess' functions
57 14         43 _export($package, blessed => \&Scalar::Util::blessed);
58 14         42 _export($package, confess => \&Carp::confess);
59              
60             # Possibly export some handy debugging stuff
61 14 50       17881 _export_xxx($package) if $ENV{PERL_MOOS_XXX};
62             }
63              
64             sub role_import {
65 2     2 0 5 my ($class, undef, %args) = @_;
66 2         4 my $package = caller;
67              
68             # Create/register a metaclass object for the package
69 2   33     18 my $metarole =
70             delete $args{metarole}
71             || $class->default_metarole;
72 2         10 my $meta = $metarole->initialize($package, %args);
73              
74             # Using 'eval' rather that exporting ensures that this method
75             # will not be cleaned up by namespace::autoclean-type things.
76 2   0 4   186 eval q{
  4   0 2   36  
  2         8843  
77             package }.$package.q{;
78             sub meta {
79             Moos::Meta::Role->initialize(
80             Scalar::Util::blessed($_[0]) || $_[0]
81             );
82             }
83             };
84              
85             # Export the 'has' helper function
86 2         10 _export($package, has => \&has, $meta);
87              
88             # Export the 'blessed' and 'confess' functions
89 2         6 _export($package, blessed => \&Scalar::Util::blessed);
90 2         5 _export($package, confess => \&Carp::confess);
91              
92             # Possibly export some handy debugging stuff
93 2 50       7 _export_xxx($package) if $ENV{PERL_MOOS_XXX};
94              
95             # Now do Role::Tiny's import stuff.
96 2         12 require Role::Tiny;
97 2         4 @_ = qw(Role::Tiny);
98 2         11 goto \&Role::Tiny::import; # preserve caller
99             }
100              
101             # Attribute generator
102             sub has {
103 25     25 1 79 my ($meta, $name) = splice(@_, 0, 2);
104 25 100       103 $name = [$name] unless ref $name;
105 25         39 my %args;
106              
107             # Support 2-arg shorthand:
108             # has foo => 42;
109 25 100       89 if (@_ % 2) {
110 6         10 my $default = shift;
111 1     1   3 my $sub =
112             ref($default) eq 'HASH' ? sub {+{%$default}} :
113 2     2   5 ref($default) eq 'ARRAY' ? sub {[@$default]} :
114 6 100   2   49 sub {$default};
  2 100       5  
115 6         19 %args = (default => $sub);
116             }
117 25         98 %args = (%args, @_);
118              
119             # Add attributes to meta class object
120 25         223 $meta->add_attribute($_ => \%args) for @$name;
121             }
122              
123             # Inheritance maker
124             sub extends {
125 15     15 1 50 my ($meta, @parents) = @_;
126 15         34 for my $parent (@parents) {
127 15         1004 eval "require $parent";
128             }
129 15         96 $meta->superclasses(@parents);
130             }
131              
132             sub with {
133 1     1 1 3 my ($meta, @roles) = @_;
134 1         6 $meta->apply_roles(@roles);
135             }
136              
137             # Use this for exports and meta-exports
138             sub _export {
139 76     76   135 my ($package, $name, $code, $meta) = @_;
140 76 100       157 if (defined $meta) {
141 44         56 my $orig = $code;
142             $code = sub {
143 27     27   501 unshift @_, $meta;
144 27         112 goto &$orig;
145 44         196 };
146             }
147 9     9   63 no strict 'refs';
  9         26  
  9         979  
148 76         86 *{"$package\::$name"} = $code;
  76         343  
149             }
150              
151             # Export the 4 debugging subs from XXX.pm
152             sub _export_xxx {
153 0     0   0 my ($package) = @_;
154 0 0       0 eval "use XXX -with => 'YAML::XS'; 1" or die $@;
155 9     9   49 no strict 'refs';
  9         16  
  9         12112  
156 0         0 _export($package, WWW => \&{__PACKAGE__ . '::WWW'});
  0         0  
157 0         0 _export($package, XXX => \&{__PACKAGE__ . '::XXX'});
  0         0  
158 0         0 _export($package, YYY => \&{__PACKAGE__ . '::YYY'});
  0         0  
159 0         0 _export($package, ZZZ => \&{__PACKAGE__ . '::ZZZ'});
  0         0  
160             }
161              
162             # The remainder of this module was heavily inspired by Moose, and tried to do
163             # what Moose does, only much less.
164             package Moos::Meta::Class;
165 9     9   133 use Carp qw(confess);
  9         15  
  9         6362  
166             our @ISA = 'Moos::Object';
167              
168             # Store all the Moos meta-class-objects in a private hash, keyed on
169             # package/class name:
170             my $meta_class_objects = {};
171              
172             # Helper method to get class name:
173 238     238   3338 sub name { $_[0]->{package} }
174              
175 408     408   1193 sub default_attribute_metaclass { 'Moos::Meta::Attribute' }
176              
177             # read-only accessor
178             sub attribute_metaclass {
179 190     190   775 $_[0]{attribute_metaclass};
180             }
181             __PACKAGE__->meta->add_attribute(
182             attribute_metaclass => {
183             is => 'ro',
184             default => \&default_attribute_metaclass,
185             _skip_setup => 1,
186             },
187             );
188              
189             # Either looking the existing meta-class-object or register a new one:
190             sub initialize {
191 408     408   715 my ($class, $package, %args) = @_;
192              
193             # Class to use to generate attribute accessors, etc
194 408   33     1605 $args{attribute_metaclass} ||= $class->default_attribute_metaclass;
195              
196             # This is a tiny version of a Moose meta-class-object.
197             # We really just need a place to keep the attributes.
198 408   66     1988 return $meta_class_objects->{$package} ||= do {
199 42         572 bless {
200             package => $package,
201             # This isn't currently used but matches Moose and is cheap.
202             attributes => {},
203             # We construct with attribute in order defined. (Unlike Moose)
204             _attributes => [],
205             %args,
206             }, $class;
207             };
208             }
209              
210             # Make a new attribute object and add it to both a hash and an array, so that
211             # we can preserve the order defined.
212             sub add_attribute {
213 190     190   255 my $self = shift;
214 190         230 my $name = shift;
215 190 50       380 my %args = @_==1 ? %{$_[0]} : @_;
  190         579  
216              
217 190         255 push @{$self->{_attributes}}, (
  190         634  
218             $self->{attributes}{$name} =
219             $self->attribute_metaclass->new(
220             name => $name,
221             associated_class => $self,
222             %args,
223             )
224             );
225             }
226              
227             {
228             my $has_subname = eval { require Sub::Name; 1 };
229             sub add_method {
230 19     19   41 my ($self, $name, $code) = @_;
231 19         66 my $pkg = $self->name;
232 19 100       97 if (ref $code) {
233 14 50       28 if ($has_subname) {
234 0         0 $code = Sub::Name::subname("$pkg\::$name", $code);
235 0         0 Moos::_export($pkg, $name, $code);
236             }
237             else {
238             # close over $code
239 14     0   882 eval "package $pkg; sub $name { goto \$code }";
  0     0   0  
  0            
240             }
241             }
242             else {
243 5     7   356 eval "package $pkg; sub $name { $code }";
  7     0   4298  
  0     0   0  
  0     0      
  0     0      
  0            
244             }
245             }
246             }
247              
248             # A tracing wrapper for debugging accessors
249             our $TRACE_EXCLUDE = +{
250             map {($_, 1)} (
251             'Some::Module some_accessor',
252             'Some::Module some_other_accessor',
253             )
254             };
255             sub _trace_accessor_calls {
256 0     0   0 require Time::HiRes;
257 0         0 my ($name, $accessor) = @_;
258             sub {
259 0     0   0 my ($pkg, $file, $line, $sub) = caller(0);
260 0 0       0 unless ($TRACE_EXCLUDE->{"$pkg $name"}) {
261 0         0 warn "$pkg $name $line\n";
262 0         0 Time::HiRes::usleep(100000);
263             }
264 0         0 goto &$accessor;
265 0         0 };
266             }
267              
268             sub superclasses {
269 9     9   55 no strict 'refs';
  9         15  
  9         11633  
270 15     15   47 my ($self, @supers) = @_;
271 15 50       48 if (@supers) {
272 15         28 @{"$self->{package}\::ISA"} = @supers;
  15         355  
273             }
274 15         33 return @{"$self->{package}\::ISA"};
  15         69  
275             }
276              
277             sub linearized_isa {
278 203     203   258 my $self = shift;
279 203         239 my %seen;
280 203         219 return grep { not $seen{$_}++ } @{ mro::get_linear_isa($self->name) };
  407         2480  
  203         366  
281             }
282              
283             sub apply_roles
284             {
285 1     1   3 my ($self, @roles) = @_;
286 1         3 my $package = $self->name;
287              
288 1         9 require Role::Tiny;
289              
290             # Load the role modules. (Role::Tiny would do this for us anyway.)
291 1         6 Role::Tiny::_load_module($_) for @roles;
292              
293             # If any of them were Moose roles, then Class::MOP will now be
294             # available to us. Use it to detect which roles have antlers.
295 1 50       32 if (my $class_of = 'Class::MOP'->can('class_of')) {
296             # Divide list of roles into Moose and non-Moose.
297 0         0 my (@moose, @nonmoose);
298 0         0 while (@roles) {
299 0         0 my $role = shift @roles;
300 0 0       0 my $list = $class_of->($role) ? \@moose : \@nonmoose;
301 0         0 push @$list, $role;
302 0 0       0 if (ref $roles[0] eq 'HASH') {
303 0         0 push @$list, shift @roles;
304             }
305             }
306             # Apply Moose roles
307 0 0 0     0 if (@moose and my $apply = 'Moose::Util'->can('apply_all_roles')) {
308 0         0 $apply->($package, @moose);
309              
310 0         0 foreach my $role (@moose) {
311 0         0 my $rolemeta = $class_of->($role);
312 0         0 my @attributes =
313 0         0 sort { $a->insertion_order <=> $b->insertion_order }
314 0         0 map { $rolemeta->get_attribute($_) }
315             $rolemeta->get_attribute_list;
316 0         0 foreach my $attr ( @attributes ) {
317 0         0 my $name = $attr->name;
318 0         0 my %args = (
319             lazy => $attr->is_lazy,
320             required => $attr->is_required,
321             is => $attr->{is},
322             _skip_setup => 1,
323             );
324 0         0 for my $arg (qw/ clearer predicate builder default documentation handles trigger /)
325             {
326 0         0 my $has = "has_$arg";
327 0 0       0 $args{$arg} = $attr->$arg if $attr->$has;
328             }
329 0         0 $self->add_attribute($name, \%args);
330             }
331             }
332             }
333             # Allow non-Moose roles to fall through
334 0         0 @roles = @nonmoose;
335             }
336              
337 1 50       4 if (@roles) {
338 1         5 'Role::Tiny'->apply_roles_to_package($package, @roles);
339              
340 1         6 my @more_roles = map {
341 1         727 keys %{ $Role::Tiny::APPLIED_TO{$_} }
  1         2  
342             } @roles;
343              
344 1         3 foreach my $role (@more_roles) {
345             # Moo::Role stashes its attributes here...
346 2 50       3 my @attributes = @{ $Role::Tiny::INFO{$role}{attributes} || [] };
  2         10  
347 2         6 while (@attributes) {
348 2         3 my $name = shift @attributes;
349 2         3 my %args = %{ shift @attributes };
  2         13  
350 2         4 $args{_skip_setup} = 1; # Moo::Role already made accessors
351 2         5 $self->add_attribute($name, \%args);
352             }
353             }
354             }
355             }
356              
357             # This is where new objects are constructed. (Moose style)
358             sub new_object {
359 13     13   63 my ($self, $params) = @_;
360 13         41 my $object = $self->_construct_instance($params);
361 12 50       154 $object->BUILDALL($params) if $object->can('BUILDALL');
362 12         66 return $object;
363             }
364              
365             sub _construct_instance {
366 13     13   26 my ($self, $params) = @_;
367 13         125 my $instance = bless {}, $self->name;
368 13         51 foreach my $attr ($self->get_all_attributes()) {
369 26         53 my $name = $attr->{name};
370 26 50       106 next if exists $instance->{$name};
371 26 100       84 if (exists $params->{$name}) {
    100          
372 11         26 $instance->{$name} = $params->{$name};
373             }
374             elsif (not $attr->{lazy}) {
375 14 50       63 if (my $builder = $attr->{builder}) {
    100          
376 0 0 0     0 $builder = "_build_$name"
377             if defined $builder && $builder eq "1";
378 0         0 $instance->{$name} = $instance->$builder();
379 0         0 next;
380             }
381             elsif (my $default = $attr->{default}) {
382 10         24 $instance->{$name} = $default->($instance);
383             }
384 14 100 66     73 if ($attr->{required} and not exists $instance->{$name}) {
385 1         193 confess "missing required attribute '$name'";
386             }
387             }
388             # Triggers only fire for explicit assignment; not defaults.
389 25 100 100     197 if (exists $attr->{trigger} and exists $params->{$name}) {
390 1         4 $attr->{trigger}->($instance, $params->{$name});
391             }
392             }
393 12         33 return $instance;
394             }
395              
396             # Return all the unique attributes in the order defined from the outer class
397             # inwards:
398             sub get_all_attributes {
399 13     13   109 my $self = shift;
400 13         19 my (@attrs, %attrs);
401 13         39 for my $package ($self->linearized_isa) {
402 27         67 my $meta = Moos::Meta::Class->initialize($package);
403 27         39 for my $attr (@{$meta->{_attributes}}) {
  27         76  
404 27         44 my $name = $attr->{name};
405 27 100       67 next if $attrs{$name};
406 26         82 push @attrs, ($attrs{$name} = $attr);
407             }
408             }
409 13         49 return @attrs;
410             }
411              
412             # Cheap introspection stuff
413             sub get_attribute {
414 0     0   0 my ($self, $name) = @_;
415 0         0 return $self->{attributes}{$name};
416             }
417              
418             sub find_attribute_by_name {
419 0     0   0 my ($self, $name) = @_;
420 0         0 for ($self->get_all_attributes) {
421 0 0       0 return $_ if $_->name eq $name;
422             }
423 0         0 return;
424             }
425              
426             # Package for roles
427             package Moos::Meta::Role;
428 9     9   66 use Carp qw(confess);
  9         22  
  9         1858  
429             our @ISA = 'Moos::Meta::Class';
430              
431             sub add_attribute {
432 2     2   4 my $self = shift;
433 2         3 my $name = shift;
434 2 50       8 my %args = @_==1 ? %{$_[0]} : @_;
  2         7  
435              
436 2         4 push @{$Role::Tiny::INFO{ $self->name }{attributes}},
  2         16  
437             $name => \%args;
438              
439 2         13 $self->SUPER::add_attribute($name, \%args);
440             }
441              
442             # Package for blessed attributes
443             package Moos::Meta::Attribute;
444 9     9   62 use Carp qw(confess);
  9         29  
  9         508  
445 9     9   25487 BEGIN { our @ISA = 'Moos::Object' };
446              
447             __PACKAGE__->meta->add_attribute($_, { is=>'ro' })
448             for qw(
449             name associated_class is isa coerce does required
450             weak_ref lazy trigger handles builder default clearer
451             predicate documentation _skip_setup
452             );
453              
454             sub _is_simple {
455 178   66 178   1801 not ( $_[0]{builder}
456             || $_[0]{default}
457             || $_[0]{trigger}
458             || $ENV{PERL_MOOS_ACCESSOR_CALLS}
459             );
460             }
461              
462             # Not sure why it is necessary to override &new here...
463             sub new {
464 190     190   245 my $class = shift;
465 190         461 my $self = bless $class->BUILDARGS(@_) => $class;
466 190         660 $self->Moos::Object::BUILDALL;
467 187         17268 return $self;
468             }
469              
470             sub BUILDARGS {
471 190     190   188 shift;
472 190 50       735 my $args = @_==1 ? $_[0] : +{@_};
473              
474             # Massage %args
475 190         304 my $name = $args->{name};
476 190 50 33     491 $args->{builder} = "_build_$name"
477             if defined $args->{builder} && $args->{builder} eq "1";
478 190 50 66     754 $args->{clearer} = $name =~ /^_/ ? "_clear$name" : "clear_$name"
    100          
479             if defined $args->{clearer} && $args->{clearer} eq "1";
480 190 50 100     536 $args->{predicate} = $name =~ /^_/ ? "_has$name" : "has_$name"
    100          
481             if defined $args->{predicate} && $args->{predicate} eq "1";
482 190 100 100     463 $args->{trigger} = do {
483 1         3 my ($trigger, $method) = "_trigger_$name";
484             sub {
485 2 50 66 2   29 $method ||= $_[0]->can($trigger)
486             or confess "method $trigger does not exist for class ".ref($_[0]);
487 2         6 goto $method;
488 1         5 };
489             } if defined $args->{trigger} && $args->{trigger} eq "1";
490 190 100       499 $args->{is} = 'rw'
491             unless defined $args->{is};
492              
493 190         537 return $args;
494             }
495              
496             sub BUILD {
497 190     190   235 my $self = shift;
498 190 50       529 my $metaclass = $self->{associated_class} or return;
499              
500 190         311 foreach (qw( name builder predicate clearer ))
501             {
502 756 100       2438 next if !exists $self->{$_};
503 198 100       1539 next if $self->{$_} =~ $VALID_NAME;
504 2 100       375 confess sprintf(
505             "invalid method name '%s' for %s",
506             $self->{$_},
507             $_ eq 'name' ? 'attribute' : $_,
508             );
509             }
510              
511 188 100       600 unless ( $self->{_skip_setup} ) {
512 177         378 $self->_setup_accessor($metaclass);
513 177 100       25625 $self->_setup_clearer($metaclass) if $self->{clearer};
514 177 100       391 $self->_setup_predicate($metaclass) if $self->{predicate};
515 177 100       813 $self->_setup_delegation($metaclass) if $self->{handles};
516             }
517             }
518              
519             # Make a Setter/Getter accessor
520             sub _setup_accessor
521             {
522 177     177   246 my ($self, $metaclass) = @_;
523 177         265 my $name = $self->{name};
524              
525 177 100       406 if ($self->_is_simple) {
526 163 50       364 if ($Moos::CAN_HAZ_XS) {
527 163 100       359 my $type = $self->{is} eq 'ro' ? 'getters' : 'accessors';
528 163         759 return Class::XSAccessor->import(
529             class => $metaclass->{package},
530             $type => [$name],
531             );
532             }
533             else {
534 0 0       0 my $accessor = $self->{is} eq 'ro'
535             ? qq{ Carp::confess("cannot set value for read-only accessor '$name'") if \@_ > 1; \$_[0]{'$name'} }
536             : qq{ \$#_ ? \$_[0]{'$name'} = \$_[1] : \$_[0]{'$name'} };
537 0         0 return $metaclass->add_method($name, $accessor);
538             }
539             }
540              
541 14         62 my ($builder, $default) = map $self->{$_}, qw(builder default);
542             my $accessor =
543             $builder ? sub {
544 0 0   0   0 $#_ ? $_[0]{$name} = $_[1] :
    0          
545             exists($_[0]{$name}) ? $_[0]{$name} :
546             ($_[0]{$name} = $_[0]->$builder);
547             } :
548             $default ? sub {
549 7 100   7   83 $#_ ? $_[0]{$name} = $_[1] :
    100          
550             exists($_[0]{$name}) ? $_[0]{$name} :
551             ($_[0]{$name} = $default->($_[0]));
552             } :
553             sub {
554 3 50   3   13 $#_ ? $_[0]{$name} = $_[1] : $_[0]{$name};
555 14 100       91 };
    50          
556              
557 14 50       66 if ($self->{is} eq 'ro') {
    100          
558 0         0 my $orig = $accessor;
559             $accessor = sub {
560 0 0   0   0 confess "cannot set value for read-only accessor '$name'" if @_ > 1;
561 0         0 goto $orig;
562 0         0 };
563             }
564              
565             elsif (exists $self->{trigger}) {
566 4 50       11 ref $self->{trigger} or confess "trigger for $name is not a reference";
567 4         5 my $orig = $accessor;
568             $accessor = sub {
569 6 100   6   20 if (@_ > 1) {
570 4 100       38 $self->{trigger}->(
571             @_[0, 1],
572             exists($_[0]{$name}) ? $_[0]{$name} : (),
573             );
574             }
575 6         25 goto $orig;
576 4         16 };
577             }
578              
579             # Dev debug thing to trace calls to accessor subs.
580 14 50       46 $accessor = _trace_accessor_calls($name, $accessor)
581             if $ENV{PERL_MOOS_ACCESSOR_CALLS};
582              
583             # Export the accessor.
584 14         38 $metaclass->add_method($name, $accessor);
585              
586 14         35 return;
587             }
588              
589             sub _setup_clearer {
590 4     4   7 my ($self, $metaclass) = @_;
591 4         9 my $name = $self->{name};
592              
593 4 50       11 my $clearer = $self->{clearer} or return;
594 4         28 $metaclass->add_method($clearer, qq{ delete \$_[0]{'$name'} });
595 4         8 return;
596             }
597              
598             sub _setup_predicate {
599 1     1   2 my ($self, $metaclass) = @_;
600 1         4 my $name = $self->{name};
601              
602 1 50       5 my $predicate = $self->{predicate} or return;
603              
604 1 50       4 if ($Moos::CAN_HAZ_XS) {
605 1         7 return Class::XSAccessor->import(
606             class => $metaclass->{package},
607             predicates => { $predicate => $name },
608             );
609             }
610              
611 0         0 $metaclass->add_method($predicate, qq{ exists \$_[0]{'$name'} });
612 0         0 return;
613             }
614              
615             sub _setup_delegation {
616 2     2   4 my ($self, $metaclass) = @_;
617 2         5 my $name = $self->{name};
618              
619 2 50       9 return unless exists $self->{handles};
620              
621 2         4 my %map;
622 2 50       17 %map = %{$self->{handles}}
  0         0  
623             if Scalar::Util::reftype($self->{handles}) eq 'HASH';
624 2 50       21 %map = map { ;$_=>$_ } @{$self->{handles}}
  2         8  
  2         6  
625             if Scalar::Util::reftype($self->{handles}) eq 'ARRAY';
626              
627 2         15 while (my ($local, $remote) = each %map) {
628 2         4 for my $method ($local, $remote) {
629 3 100       18 next if $method =~ $VALID_NAME;
630 1         139 confess "invalid delegated method name '$method'";
631             }
632 1 50       3 if ($self->_is_simple) {
633 1         7 $metaclass->add_method($local, qq{ shift->{$name}->$remote(\@_) });
634             }
635             else {
636 0         0 $metaclass->add_method($local, qq{ shift->$name\->$remote(\@_) });
637             }
638             }
639 1         5 return;
640             }
641              
642             # This is the default base class for all Moos classes:
643             package Moos::Object;
644              
645             # Moos constructor
646             sub new {
647 13     13   183 my $class = shift;
648 13   33     84 my $real_class = Scalar::Util::blessed($class) || $class;
649 13         118 my $params = $real_class->BUILDARGS(@_);
650 13         47 return Moos::Meta::Class->initialize($real_class)->new_object($params);
651             }
652              
653             # A default BUILDARGS
654             sub BUILDARGS {
655 13     13   26 shift;
656 13 100 100     94 return +{(@_ and ref($_[0]) eq 'HASH') ? %{$_[0]} : @_};
  1         5  
657             }
658              
659             # A default BUILDALL
660             sub BUILDALL {
661 202 100   202   864 return unless $_[0]->can('BUILD');
662 190         284 my ($self, $params) = @_;
663 190         492 for my $package (reverse $self->meta->linearized_isa) {
664 9     9   88 no strict 'refs';
  9         28  
  9         940  
665 380 100       583 if (defined &{"$package\::BUILD"}) {
  380         1943  
666 190         212 &{"$package\::BUILD"}($self, $params);
  190         665  
667             }
668             }
669             }
670              
671             # A Data::Dumper method. (Moose has it. No cost.)
672             sub dump {
673 9     9   61 no warnings 'once';
  9         17  
  9         13440  
674 0     0   0 my $self = shift;
675 0         0 require Data::Dumper;
676 0 0       0 local $Data::Dumper::Maxdepth = shift if @_;
677 0         0 Data::Dumper::Dumper $self;
678             }
679              
680             # Retrieve the Moos meta-class-object.
681             sub meta {
682 352   66 352   1830 Moos::Meta::Class->initialize(Scalar::Util::blessed($_[0]) || $_[0]);
683             }
684              
685             sub does {
686 0     0   0 my ($self, $role) = @_;
687 0 0 0     0 return 1
688             if $INC{'Role/Tiny.pm'}
689             && Role::Tiny::does_role($self, $role);
690 0 0 0     0 return 1
      0        
691             if $INC{'Moose/Util.pm'}
692             && Moose::Util->can('does_role')
693             && Moose::Util::does_role($self, $role);
694 0         0 return 0;
695             }
696              
697             sub DOES {
698 0     0   0 my ($self, $role) = @_;
699 0   0     0 my $universal_does = UNIVERSAL->can('DOES') || UNIVERSAL->can('isa');
700 0 0       0 $self->does($role) or $self->$universal_does($role);
701             }
702              
703             1;