File Coverage

blib/lib/Sub/Meta/Param.pm
Criterion Covered Total %
statement 120 120 100.0
branch 68 68 100.0
condition 15 15 100.0
subroutine 33 33 100.0
pod 28 28 100.0
total 264 264 100.0


line stmt bran cond sub pod time code
1             package Sub::Meta::Param;
2 45     45   2381754 use 5.010;
  45         213  
3 45     45   236 use strict;
  45         104  
  45         860  
4 45     45   212 use warnings;
  45         88  
  45         1987  
5              
6             our $VERSION = "0.14";
7              
8 45     45   306 use Scalar::Util ();
  45         114  
  45         1935  
9              
10             use overload
11 45         452 fallback => 1,
12             eq => \&is_same_interface,
13 45     45   307 ;
  45         142  
14              
15             my %DEFAULT = ( named => 0, optional => 0, invocant => 0 );
16              
17             sub new {
18 255     255 1 157336 my ($class, @args) = @_;
19 255         494 my $v = $args[0];
20 255 100 100     1228 my %args = @args == 1 ? ref $v && (ref $v eq 'HASH') ? %{$v}
  76 100       317  
21             : ( type => $v )
22             : @args;
23              
24 255 100       797 $args{optional} = !delete $args{required} if exists $args{required};
25 255 100       638 $args{named} = !delete $args{positional} if exists $args{positional};
26 255 100       586 $args{type} = delete $args{isa} if exists $args{isa};
27              
28 255         1225 %args = (%DEFAULT, %args);
29              
30 255         1423 return bless \%args => $class;
31             }
32              
33 165   100 165 1 37330 sub name() { my $self = shift; return $self->{name} // '' }
  165         1281  
34 583     583 1 22551 sub type() { my $self = shift; return $self->{type} }
  583         3655  
35 61     61 1 9769 sub default() { my $self = shift; return $self->{default} } ## no critic (ProhibitBuiltinHomonyms)
  61         146  
36 61     61 1 9414 sub coerce() { my $self = shift; return $self->{coerce} }
  61         147  
37 581     581 1 11974 sub optional() { my $self = shift; return !!$self->{optional} }
  581         4063  
38 144     144 1 11723 sub required() { my $self = shift; return !$self->{optional} }
  144         562  
39 654     654 1 14260 sub named() { my $self = shift; return !!$self->{named} }
  654         3050  
40 217     217 1 11540 sub positional() { my $self = shift; return !$self->{named} }
  217         786  
41 61     61 1 11728 sub invocant() { my $self = shift; return !!$self->{invocant} }
  61         180  
42              
43 548     548 1 12057 sub has_name() { my $self = shift; return defined $self->{name} }
  548         2810  
44 433     433 1 11936 sub has_type() { my $self = shift; return defined $self->{type} }
  433         1719  
45 61     61 1 11256 sub has_default() { my $self = shift; return defined $self->{default} }
  61         178  
46 61     61 1 11355 sub has_coerce() { my $self = shift; return defined $self->{coerce} }
  61         179  
47              
48 3     3 1 11057 sub set_name { my ($self, $v) = @_; $self->{name} = $v; return $self }
  3         39  
  3         19  
49 4     4 1 10663 sub set_type { my ($self, $v) = @_; $self->{type} = $v; return $self }
  4         31  
  4         25  
50 4     4 1 12245 sub set_default { my ($self, $v) = @_; $self->{default} = $v; return $self }
  4         37  
  4         29  
51 4     4 1 10842 sub set_coerce { my ($self, $v) = @_; $self->{coerce} = $v; return $self }
  4         31  
  4         25  
52 6 100   6 1 7770 sub set_optional { my ($self, $v) = @_; $self->{optional} = !!(defined $v ? $v : 1); return $self }
  6         42  
  6         26  
53 6 100   6 1 7896 sub set_required { my ($self, $v) = @_; $self->{optional} = !(defined $v ? $v : 1); return $self }
  6         20  
  6         26  
54 6 100   6 1 7738 sub set_named { my ($self, $v) = @_; $self->{named} = !!(defined $v ? $v : 1); return $self }
  6         42  
  6         25  
55 6 100   6 1 7924 sub set_positional { my ($self, $v) = @_; $self->{named} = !(defined $v ? $v : 1); return $self }
  6         19  
  6         24  
56 71 100   71 1 14203 sub set_invocant { my ($self, $v) = @_; $self->{invocant} = !!(defined $v ? $v : 1); return $self }
  71         450  
  71         178  
57              
58             # alias
59             sub isa_() :method; # NOT isa
60             *isa_ = \&type;
61              
62             sub set_isa;
63             *set_isa = \&set_type;
64              
65             sub is_same_interface {
66 117     117 1 257 my ($self, $other) = @_;
67              
68 117 100 100     762 return unless Scalar::Util::blessed($other) && $other->isa('Sub::Meta::Param');
69              
70 107 100       294 if ($self->has_name) {
71 16 100       41 return unless $self->name eq $other->name
72             }
73             else {
74 91 100       209 return if $other->has_name
75             }
76              
77 97 100       251 if ($self->has_type) {
78 68 100 100     179 return unless $self->type eq ($other->type // '');
79             }
80             else {
81 29 100       67 return if $other->has_type
82             }
83              
84 73 100       201 return unless $self->optional eq $other->optional;
85              
86 68 100       176 return unless $self->named eq $other->named;
87              
88 63         243 return !!1;
89             }
90              
91             sub is_relaxed_same_interface {
92 98     98 1 196 my ($self, $other) = @_;
93              
94 98 100 100     581 return unless Scalar::Util::blessed($other) && $other->isa('Sub::Meta::Param');
95              
96 96 100       231 if ($self->has_name) {
97 14 100       32 return unless $self->name eq $other->name
98             }
99              
100 91 100       218 if ($self->has_type) {
101 57 100 100     152 return unless $self->type eq ($other->type // '');
102             }
103              
104 71 100       174 return unless $self->optional eq $other->optional;
105              
106 66 100       166 return unless $self->named eq $other->named;
107              
108 61         218 return !!1;
109             }
110              
111             sub is_same_interface_inlined {
112 24     24 1 70 my ($self, $v) = @_;
113              
114 24         39 my @src;
115 24         96 push @src => sprintf("Scalar::Util::blessed(%s) && %s->isa('Sub::Meta::Param')", $v, $v);
116              
117 24 100       73 push @src => $self->has_name ? sprintf("'%s' eq %s->name", $self->name, $v)
118             : sprintf('!%s->has_name', $v);
119              
120 24 100       78 push @src => $self->has_type ? sprintf("'%s' eq (%s->type // '')", "@{[$self->type]}", $v)
  15         53  
121             : sprintf('!%s->has_type', $v);
122              
123 24         105 push @src => sprintf("'%s' eq %s->optional", $self->optional, $v);
124              
125 24         90 push @src => sprintf("'%s' eq %s->named", $self->named, $v);
126              
127 24         1223 return join "\n && ", @src;
128             }
129              
130             sub is_relaxed_same_interface_inlined {
131 30     30 1 88 my ($self, $v) = @_;
132              
133 30         49 my @src;
134 30         493 push @src => sprintf("Scalar::Util::blessed(%s) && %s->isa('Sub::Meta::Param')", $v, $v);
135              
136 30 100       79 push @src => sprintf("'%s' eq %s->name", $self->name, $v) if $self->has_name;
137              
138 30 100       80 push @src => sprintf("'%s' eq (%s->type // '')", "@{[$self->type]}", $v) if $self->has_type;
  21         52  
139              
140 30         191 push @src => sprintf("'%s' eq %s->optional", $self->optional, $v);
141              
142 30         96 push @src => sprintf("'%s' eq %s->named", $self->named, $v);
143              
144 30         866 return join "\n && ", @src;
145             }
146              
147             sub display {
148 66     66 1 100 my $self = shift;
149              
150 66         101 my $s = '';
151 66 100       129 $s .= $self->type if $self->has_type;
152 66 100       219 if ($self->has_name) {
153 10 100       17 $s .= sprintf("%s%s%s",
    100          
154             $self->has_type ? ' ' : '',
155             $self->named ? ':' : '',
156             $self->name);
157             }
158 66         295 return $s;
159             }
160              
161              
162             1;
163             __END__