subclassing and role composition for attributes
[gitmo/Moo.git] / lib / Class / Tiny.pm
1 package Class::Tiny;
2
3 use strictures 1;
4 use Class::Tiny::_Utils;
5
6 our %MAKERS;
7
8 sub import {
9   my $target = caller;
10   strictures->import;
11   *{_getglob("${target}::extends")} = sub {
12     *{_getglob("${target}::ISA")} = \@_;
13   };
14   *{_getglob("${target}::with")} = sub {
15     require Role::Tiny;
16     die "Only one role supported at a time by with" if @_ > 1;
17     Role::Tiny->apply_role_to_package($_[0], $target);
18   };
19   *{_getglob("${target}::has")} = sub {
20     my ($name, %spec) = @_;
21     ($MAKERS{$target}{accessor} ||= do {
22       require Method::Generate::Accessor;
23       Method::Generate::Accessor->new
24     })->generate_method($target, $name, \%spec);
25     ($MAKERS{$target}{constructor} ||= do {
26       require Method::Generate::Constructor;
27       Method::Generate::Constructor
28         ->new(package => $target)
29         ->install_delayed
30         ->register_attribute_specs(do {
31           my @spec;
32           if (my $super = do { no strict 'refs'; ${"${target}::ISA"}[0] }) {
33             if (my $con = $MAKERS{$super}{constructor}) {
34               @spec = %{$con->all_attribute_specs};
35             }
36           }
37           @spec;
38         });
39     })->register_attribute_specs($name, \%spec);
40   };
41   foreach my $type (qw(before after around)) {
42     *{_getglob "${target}::${type}"} = sub {
43       _install_modifier($target, $type, @_);
44     };
45   }
46   {
47     no strict 'refs';
48     @{"${target}::ISA"} = do {
49       require Class::Tiny::Object; ('Class::Tiny::Object');
50     } unless @{"${target}::ISA"};
51   }
52 }
53
54 1;