File Coverage

blib/lib/Mojo/Shortcut.pm
Criterion Covered Total %
statement 61 61 100.0
branch 25 30 83.3
condition 6 10 60.0
subroutine 11 11 100.0
pod 4 4 100.0
total 107 116 92.2


line stmt bran cond sub pod time code
1             package Mojo::Shortcut;
2 6     6   502985 use Mojo::Base -base;
  6         10  
  6         44  
3 6     6   3467 use experimental qw( signatures postderef );
  6         3526  
  6         30  
4              
5 6     6   644 use Carp 'croak';
  6         9  
  6         251  
6 6     6   26 use List::Util 'first';
  6         7  
  6         456  
7 6     6   2161 use Mojo::Loader;
  6         192910  
  6         66  
8 6     6   195 use Mojo::Util 'camelize';
  6         8  
  6         3698  
9              
10             has namespaces => sub { croak 'Shortcut::namespaces should be defined' };
11              
12             has base_classes => sub { [] };
13             has ['action', 'moniker'];
14              
15 14 50   14 1 2878 sub new($self, @args) {
  14         27  
  14         63  
  14         21  
16 14 100       51 if (@args % 2) {
17 12         117 my ($moniker, $action) = split '#', shift @args;
18 12         41 push @args, moniker => $moniker, action => $action;
19             }
20 14         93 $self->SUPER::new(@args);
21             }
22              
23 3 50   3 1 1185 sub invoke($self, @args) {
  3         7  
  3         17  
  3         4  
24 3         5 my $cb;
25 3 100       10 unless ($cb = $self->cb) {
26 1   33     3 my $cl = $self->class // $self->moniker // 'undefined';
      50        
27 1   50     19 my $act = $self->action // 'undefined';
28 1         239 croak "can't invoke $cl::$act";
29             }
30              
31 2         21 $cb->($self->class->new(@args));
32             }
33              
34 8 50   8 1 1031 sub cb($self, @args) {
  8         13  
  8         162  
  8         10  
35 8 100       226 croak 'action must be defined' unless my $action = $self->action;
36 7 100       81 my $class = $self->class or return;
37 5         9 \&{"$class::$action"};
  5         36  
38             }
39              
40 18 50   18 1 612 sub class($self) {
  18 50       42  
  18         24  
  18         21  
41 18         529 my $namespaces = $self->namespaces;
42 18 100       149 $namespaces = [$namespaces] unless ref $namespaces;
43 18         39 my @classes = map { join '::', $_, camelize $self->moniker } @$namespaces;
  30         793  
44              
45 18         279 foreach my $cur (@classes) {
46 26 100       241 if (my $e = Mojo::Loader->load($cur)) {
47 2 100       1373 ref $e ? die $e : next;
48             }
49              
50             # is not child of any from base_classes
51 24 100       942437 if ($self->base_classes->@*) {
52 12 100   12   260 next unless first { $cur->isa($_) } $self->base_classes->@*;
  12         184  
53             }
54              
55             # action defined but not found
56 18 100 100     423 next if $self->action && !$cur->can($self->action);
57 12         440 return $cur;
58             }
59              
60             # nothing found
61 5         231 return;
62             }
63              
64             1;
65              
66             # ABSTRACT: Mojo::Abstract - loading classes and methods by short#cuts
67              
68             __END__