Add predicates to the informational Mouse::Attribute attributes
[gitmo/Mouse.git] / lib / Mouse / Object.pm
CommitLineData
c3398f5b 1#!/usr/bin/env perl
2package Mouse::Object;
3use strict;
4use warnings;
5use MRO::Compat;
6
7use Scalar::Util 'blessed';
8use Carp 'confess';
9
10sub new {
11 my $class = shift;
12 my %args = @_;
13 my $instance = bless {}, $class;
14
15 for my $attribute ($class->meta->attributes) {
16 my $key = $attribute->init_arg;
17 my $default;
18
19 if (!exists($args{$key})) {
20 if (exists($attribute->{default})) {
21 unless ($attribute->{lazy}) {
22 if (ref($attribute->{default}) eq 'CODE') {
23 $instance->{$key} = $attribute->{default}->();
24 Scalar::Util::weaken($instance->{$key})
25 if $attribute->{weak_ref};
26 }
27 else {
28 $instance->{$key} = $attribute->{default};
29 Scalar::Util::weaken($instance->{$key})
30 if $attribute->{weak_ref};
31 }
32 }
33 }
34 else {
35 if ($attribute->{required}) {
36 confess "Attribute '$attribute->{name}' is required";
37 }
38 }
39 }
40
41 if (exists($args{$key})) {
42 $instance->{$key} = $args{$key};
43 Scalar::Util::weaken($instance->{$key})
44 if $attribute->{weak_ref};
45
46 if ($attribute->{trigger}) {
47 $attribute->{trigger}->($instance, $args{$key}, $attribute);
48 }
49 }
50 }
51
52 $instance->BUILDALL(\%args);
53
54 return $instance;
55}
56
57sub DESTROY { shift->DEMOLISHALL }
58
59sub BUILDALL {
60 my $self = shift;
61
62 # short circuit
63 return unless $self->can('BUILD');
64
65 no strict 'refs';
66
67 for my $class ($self->meta->linearized_isa) {
68 my $code = *{ $class . '::BUILD' }{CODE}
69 or next;
70 $code->($self, @_);
71 }
72}
73
74sub DEMOLISHALL {
75 my $self = shift;
76
77 # short circuit
78 return unless $self->can('DEMOLISH');
79
80 no strict 'refs';
81
82 for my $class ($self->meta->linearized_isa) {
83 my $code = *{ $class . '::DEMOLISH' }{CODE}
84 or next;
85 $code->($self, @_);
86 }
87}
88
891;
90
91__END__
92
93=head1 NAME
94
95Mouse::Object - we don't need to steenkin' constructor
96
97=head1 METHODS
98
99=head2 new arguments -> object
100
101Instantiates a new Mouse::Object. This is obviously intended for subclasses.
102
103=head2 BUILDALL \%args
104
105Calls L</BUILD> on each class in the class hierarchy. This is called at the
106end of L</new>.
107
108=head2 BUILD \%args
109
110You may put any business logic initialization in BUILD methods. You don't
111need to redispatch or return any specific value.
112
113=head2 DEMOLISHALL
114
115Calls L</DEMOLISH> on each class in the class hierarchy. This is called at
116L</DESTROY> time.
117
118=head2 DEMOLISH
119
120You may put any business logic deinitialization in DEMOLISH methods. You don't
121need to redispatch or return any specific value.
122
123=cut
124