File Coverage

blib/lib/MooX/Aliases.pm
Criterion Covered Total %
statement 67 67 100.0
branch 20 22 90.9
condition 8 9 88.8
subroutine 10 10 100.0
pod n/a
total 105 108 97.2


line stmt bran cond sub pod time code
1             package MooX::Aliases;
2 8     8   331623 use strictures 1;
  8         47  
  8         171  
3              
4             our $VERSION = '0.001005';
5             $VERSION = eval $VERSION;
6              
7 8     8   635 use Carp;
  8         13  
  8         661  
8 8     8   7237 use Class::Method::Modifiers qw(install_modifier);
  8         12185  
  8         815  
9              
10             sub import {
11 10     10   1674 my ($class) = @_;
12 10         22 my $target = caller;
13              
14 8 50   8   54 my $around = do { no strict 'refs'; \&{"${target}::around"} }
  8         12  
  8         1096  
  10         15  
  10         12  
  10         73  
15             or croak "$target is not a Moo class or role";
16              
17             my $make_alias = sub {
18 26     26   121 my ($from, $to) = @_;
19 26 100       180 if (!$target->can($to)) {
20 1         214 croak "Cannot find method $to to alias";
21             }
22              
23 8     8   50 no strict 'refs';
  8         11  
  8         853  
24 25         150 *{"${target}::${from}"} = sub {
25 33     33   15259 goto &{$_[0]->can($to)};
  33         427  
26 25         91 };
27 10         116 };
28              
29             {
30 8     8   39 no strict 'refs';
  8         13  
  8         3225  
  10         13  
31 10         12 *{"${target}::alias"} = $make_alias;
  10         48  
32             }
33              
34 10         14 my $installed_buildargs;
35             my %init_args;
36             install_modifier $target, 'around', 'has', sub {
37 20     20   4931 my $orig = shift;
38 20         90 my ($attr, %opts) = @_;
39              
40 20         53 my $aliases = delete $opts{alias};
41 20 100 100     164 $aliases = [ $aliases ]
42             if $aliases && !ref $aliases;
43              
44 20 100 100     106 return $orig->($attr, %opts)
45             unless $aliases && @$aliases;
46              
47 2         221 my $attr_name
48             = !ref $attr ? $attr
49 17 100       56 : @{$attr} == 1 ? $attr->[0]
    100          
50             : croak "Cannot make alias to list of attributes";
51              
52 16         41 $attr_name =~ s/^\+//;
53              
54 16 50       53 my $name = defined $opts{init_arg} ? $opts{init_arg} : $attr_name;
55 16         39 my @names = @$aliases;
56 16 100 66     80 if (!exists $opts{init_arg} || defined $opts{init_arg}) {
57 13         33 unshift @names, $name;
58             }
59 16         45 $init_args{$name} = \@names;
60              
61 16         84 my $out = $orig->($attr, %opts);
62              
63 16         105889 for my $alias (@$aliases) {
64 22         60 $make_alias->($alias => $attr_name);
65             }
66              
67 16 100       42 if (!$installed_buildargs) {
68 9         15 $installed_buildargs = 1;
69             $around->('BUILDARGS', sub {
70 14         19793 my $orig = shift;
71 14         91 my $self = shift;
72 14         169 my $args = $self->$orig(@_);
73 14         150 for my $attr (keys %init_args) {
74 27         26 my @init = grep { exists $args->{$_} } (@{$init_args{$attr}});
  55         109  
  27         53  
75 27 100       107 if (@init > 1) {
    100          
76 1         208 croak "Conflicting init_args: (" . join(', ', @init) . ")";
77             }
78             elsif (@init == 1) {
79 7         20 $args->{$attr} = delete $args->{$init[0]};
80             }
81             }
82 13         224 return $args;
83 9         61 });
84             }
85              
86 16         2206 return $out;
87 10         67 };
88             }
89              
90             1;
91              
92             __END__