File Coverage

blib/lib/Moxie.pm
Criterion Covered Total %
statement 18 20 90.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 25 27 92.5


line stmt bran cond sub pod time code
1             package Moxie;
2             # ABSTRACT: Not Another Moose Clone
3              
4 43     43   2272351 use v5.22;
  43         478  
5 43     43   192 use warnings;
  43         69  
  43         1199  
6 43         204 use experimental qw[
7             signatures
8             postderef
9 43     43   10810 ];
  43         107019  
10              
11 43     43   6889 use experimental (); # need this later when we load features
  43         73  
  43         566  
12 43     43   9934 use Module::Runtime (); # load things so they DWIM
  43         42920  
  43         855  
13 43     43   11170 use BEGIN::Lift (); # fake some keywords
  43         159151  
  43         949  
14 43     43   11328 use Method::Traits (); # for accessor/method generators
  0            
  0            
15              
16             use MOP;
17             use MOP::Util;
18              
19             use Moxie::Object;
20             use Moxie::Object::Immutable;
21             use Moxie::Traits::Provider;
22              
23             our $VERSION = '0.05';
24             our $AUTHORITY = 'cpan:STEVAN';
25              
26             sub import ($class, %opts) {
27             # get the caller ...
28             my $caller = caller;
29              
30             # make the assumption that if we are
31             # loaded outside of main then we are
32             # likely being loaded in a class, so
33             # turn on all the features
34             if ( $caller ne 'main' ) {
35             $class->import_into( $caller, \%opts );
36             }
37             }
38              
39             sub import_into ($class, $caller, $opts) {
40             # NOTE:
41             # create the meta-object, we start
42             # with this as a role, but it will
43             # get "cast" to a class if there
44             # is a need for it.
45             my $meta = MOP::Role->new( name => $caller );
46              
47             # turn on strict/warnings
48             strict->import;
49             warnings->import;
50              
51             # so we can have fun with attributes ...
52             warnings->unimport('reserved');
53              
54             # turn on signatures and more
55             experimental->import($_) foreach qw[
56             signatures
57              
58             postderef
59             postderef_qq
60              
61             current_sub
62             lexical_subs
63              
64             say
65             state
66             ];
67              
68             # turn on refaliasing if we have it ...
69             experimental->import('refaliasing') if $] >= 5.022;
70              
71             # turn on declared refs if we have it ...
72             experimental->import('declared_refs') if $] >= 5.026;
73              
74             # import has, extend and with keyword
75              
76             BEGIN::Lift::install(
77             ($caller, 'has') => sub ($name, @args) {
78              
79             # NOTE:
80             # Handle the simple case of `has $name => $code`
81             # by converting it into the more complex
82             # `has $name => %opts` version, just easier
83             # to maintain internal consistency.
84             # - SL
85              
86             @args = ( default => $args[0] )
87             if scalar @args == 1
88             && ref $args[0] eq 'CODE';
89              
90             my $initializer = MOP::Slot::Initializer->new(
91             within_package => $meta->name,
92             @args
93             );
94              
95             $meta->add_slot( $name, $initializer );
96             return;
97             }
98             );
99              
100             BEGIN::Lift::install(
101             ($caller, 'extends') => sub (@isa) {
102             Module::Runtime::use_package_optimistically( $_ ) foreach @isa;
103             ($meta->isa('MOP::Class')
104             ? $meta
105             : do {
106             # FIXME:
107             # This is gross ... - SL
108             Internals::SvREADONLY( $$meta, 0 );
109             bless $meta => 'MOP::Class'; # cast into class
110             Internals::SvREADONLY( $$meta, 1 );
111             $meta;
112             }
113             )->set_superclasses( @isa );
114             return;
115             }
116             );
117              
118             BEGIN::Lift::install(
119             ($caller, 'with') => sub (@does) {
120             Module::Runtime::use_package_optimistically( $_ ) foreach @does;
121             $meta->set_roles( @does );
122             return;
123             }
124             );
125              
126             # setup the base traits, and
127             my @traits = ('Moxie::Traits::Provider');
128             # and anything we were asked to load ...
129             push @traits => $opts->{'traits'}->@* if exists $opts->{'traits'};
130              
131             # then schedule the trait collection ...
132             Method::Traits->import_into( $meta, @traits );
133              
134             # install our class finalizer
135             MOP::Util::defer_until_UNITCHECK(sub {
136              
137             # pre-populate the cache for all the slots (if it is a class)
138             MOP::Util::inherit_slots( $meta );
139              
140             # apply roles ...
141             MOP::Util::compose_roles( $meta );
142              
143             # TODO:
144             # Consider locking the %HAS hash now, this will
145             # prevent anyone from adding new fields after
146             # compile time.
147             # - SL
148              
149             });
150             }
151              
152             1;
153              
154             __END__