File Coverage

blib/lib/Kavorka/TraitFor/Sub/fresh.pm
Criterion Covered Total %
statement 23 23 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 31 31 100.0


line stmt bran cond sub pod time code
1 1     1   445 use 5.014;
  1         3  
2 1     1   4 use strict;
  1         1  
  1         18  
3 1     1   3 use warnings;
  1         0  
  1         58  
4              
5             package Kavorka::TraitFor::Sub::fresh;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.037';
9              
10 1     1   3 use Moo::Role;
  1         1  
  1         6  
11 1     1   725 use Types::Standard qw(Any);
  1         51956  
  1         9  
12 1     1   561 use Sub::Util ();
  1         1  
  1         20  
13 1     1   4 use Carp qw(croak);
  1         1  
  1         59  
14 1     1   6 use namespace::sweep;
  1         1  
  1         8  
15              
16             my $stash_name = sub {
17             Sub::Util::subname($_[0]) =~ m/^(.+)::(.+?)$/ ? $1 : undef;
18             };
19              
20             before install_sub => sub
21             {
22             my $self = shift;
23            
24             croak("The 'fresh' trait cannot be applied to lexical methods")
25             if $self->is_lexical;
26            
27             croak("The 'fresh' trait cannot be applied to anonymous methods")
28             if $self->is_anonymous;
29            
30             croak("The 'fresh' trait may only be applied to methods")
31             if $self->invocation_style ne 'method';
32            
33             my ($pkg, $name) = ($self->qualified_name =~ /^(.+)::(\w+)$/);
34             my $existing = $pkg->can($name) or return;
35             my $existing_source = $stash_name->($existing);
36            
37             if ($pkg->isa($existing_source) or $existing_source eq 'UNIVERSAL')
38             {
39             croak("Method '$name' is inherited from '$existing_source'; not fresh");
40             }
41            
42             if ($pkg->DOES($existing_source))
43             {
44             croak("Method '$name' is provided by role '$existing_source'; not fresh");
45             }
46            
47             croak("Method '$name' already exists in inheritance hierarchy; possible namespace pollution; not fresh");
48             };
49              
50             1;