fb7415d0cffbf4f176223fe7fb8f87260b66b98a
[gitmo/Role-Tiny.git] / lib / Moo / Object.pm
1 package Moo::Object;
2
3 use strictures 1;
4
5 our %NO_BUILD;
6 our %NO_DEMOLISH;
7 our $BUILD_MAKER;
8 our $DEMOLISH_MAKER;
9
10 sub new {
11   my $class = shift;
12   $NO_BUILD{$class} and
13     return bless({ ref($_[0]) eq 'HASH' ? %{$_[0]} : @_ }, $class);
14   $NO_BUILD{$class} = !$class->can('BUILD') unless exists $NO_BUILD{$class};
15   $NO_BUILD{$class}
16     ? bless({ ref($_[0]) eq 'HASH' ? %{$_[0]} : @_ }, $class)
17     : do {
18         my $proto = ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
19         bless({ %$proto }, $class)->BUILDALL($proto);
20       };
21 }
22
23 # Inlined into Method::Generate::Constructor::_generate_args() - keep in sync
24 sub BUILDARGS {
25     my $class = shift;
26     if ( scalar @_ == 1 ) {
27         unless ( defined $_[0] && ref $_[0] eq 'HASH' ) {
28             die "Single parameters to new() must be a HASH ref"
29                 ." data => ". $_[0] ."\n";
30         }
31         return { %{ $_[0] } };
32     }
33     elsif ( @_ % 2 ) {
34         die "The new() method for $class expects a hash reference or a key/value list."
35                 . " You passed an odd number of arguments\n";
36     }
37     else {
38         return {@_};
39     }
40 }
41
42 sub BUILDALL {
43   my $self = shift;
44   $self->${\(($BUILD_MAKER ||= do {
45     { local $@; require Method::Generate::BuildAll; }
46     Method::Generate::BuildAll->new
47   })->generate_method(ref($self)))}(@_);
48 }
49
50 sub DEMOLISHALL {
51   my $self = shift;
52   $self->${\(($DEMOLISH_MAKER ||= do {
53     { local $@; require Method::Generate::DemolishAll; }
54     Method::Generate::DemolishAll->new
55   })->generate_method(ref($self)))}(@_);
56 }
57
58 sub DESTROY {
59   my $self = shift;
60
61   my $class = ref($self);
62
63   $NO_DEMOLISH{$class} = !$class->can('DEMOLISH')
64     unless exists $NO_DEMOLISH{$class};
65
66   return if $NO_DEMOLISH{$class};
67
68   my $e = do {
69     local $?;
70     local $@;
71     require Moo::_Utils;
72     eval {
73       $self->DEMOLISHALL($Moo::_Utils::_in_global_destruction);
74     };
75     $@;
76   };
77
78   no warnings 'misc';
79   die $e if $e; # rethrow
80 }
81
82 sub does {
83   { local $@; require Role::Tiny; }
84   { no warnings 'redefine'; *does = \&Role::Tiny::does_role }
85   goto &Role::Tiny::does_role;
86 }
87
88 1;