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   1975146 use 5.010;
  45         178  
3 45     45   189 use strict;
  45         74  
  45         1043  
4 45     45   222 use warnings;
  45         71  
  45         1486  
5              
6             our $VERSION = "0.15";
7              
8 45     45   234 use Scalar::Util ();
  45         81  
  45         1508  
9              
10             use overload
11 45         418 fallback => 1,
12             eq => \&is_same_interface,
13 45     45   320 ;
  45         81  
14              
15             my %DEFAULT = ( named => 0, optional => 0, invocant => 0 );
16              
17             sub new {
18 255     255 1 138262 my ($class, @args) = @_;
19 255         678 my $v = $args[0];
20 255 100 100     915 my %args = @args == 1 ? ref $v && (ref $v eq 'HASH') ? %{$v}
  76 100       241  
21             : ( type => $v )
22             : @args;
23              
24 255 100       562 $args{optional} = !delete $args{required} if exists $args{required};
25 255 100       484 $args{named} = !delete $args{positional} if exists $args{positional};
26 255 100       440 $args{type} = delete $args{isa} if exists $args{isa};
27              
28 255         878 %args = (%DEFAULT, %args);
29              
30 255         1093 return bless \%args => $class;
31             }
32              
33 165   100 165 1 29080 sub name() { my $self = shift; return $self->{name} // '' }
  165         1003  
34 583     583 1 18100 sub type() { my $self = shift; return $self->{type} }
  583         2932  
35 61     61 1 8108 sub default() { my $self = shift; return $self->{default} } ## no critic (ProhibitBuiltinHomonyms)
  61         127  
36 61     61 1 7762 sub coerce() { my $self = shift; return $self->{coerce} }
  61         144  
37 581     581 1 9399 sub optional() { my $self = shift; return !!$self->{optional} }
  581         3066  
38 144     144 1 9704 sub required() { my $self = shift; return !$self->{optional} }
  144         425  
39 654     654 1 10092 sub named() { my $self = shift; return !!$self->{named} }
  654         2346  
40 217     217 1 9409 sub positional() { my $self = shift; return !$self->{named} }
  217         580  
41 61     61 1 9244 sub invocant() { my $self = shift; return !!$self->{invocant} }
  61         143  
42              
43 548     548 1 9690 sub has_name() { my $self = shift; return defined $self->{name} }
  548         2195  
44 433     433 1 9428 sub has_type() { my $self = shift; return defined $self->{type} }
  433         1328  
45 61     61 1 9152 sub has_default() { my $self = shift; return defined $self->{default} }
  61         131  
46 61     61 1 9650 sub has_coerce() { my $self = shift; return defined $self->{coerce} }
  61         150  
47              
48 3     3 1 7505 sub set_name { my ($self, $v) = @_; $self->{name} = $v; return $self }
  3         25  
  3         10  
49 4     4 1 11045 sub set_type { my ($self, $v) = @_; $self->{type} = $v; return $self }
  4         27  
  4         23  
50 4     4 1 11527 sub set_default { my ($self, $v) = @_; $self->{default} = $v; return $self }
  4         35  
  4         24  
51 4     4 1 9241 sub set_coerce { my ($self, $v) = @_; $self->{coerce} = $v; return $self }
  4         25  
  4         23  
52 6 100   6 1 6831 sub set_optional { my ($self, $v) = @_; $self->{optional} = !!(defined $v ? $v : 1); return $self }
  6         35  
  6         22  
53 6 100   6 1 6778 sub set_required { my ($self, $v) = @_; $self->{optional} = !(defined $v ? $v : 1); return $self }
  6         17  
  6         21  
54 6 100   6 1 6478 sub set_named { my ($self, $v) = @_; $self->{named} = !!(defined $v ? $v : 1); return $self }
  6         36  
  6         22  
55 6 100   6 1 6465 sub set_positional { my ($self, $v) = @_; $self->{named} = !(defined $v ? $v : 1); return $self }
  6         19  
  6         20  
56 71 100   71 1 15582 sub set_invocant { my ($self, $v) = @_; $self->{invocant} = !!(defined $v ? $v : 1); return $self }
  71         346  
  71         137  
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 219 my ($self, $other) = @_;
67              
68 117 100 100     595 return unless Scalar::Util::blessed($other) && $other->isa('Sub::Meta::Param');
69              
70 107 100       223 if ($self->has_name) {
71 16 100       25 return unless $self->name eq $other->name
72             }
73             else {
74 91 100       140 return if $other->has_name
75             }
76              
77 97 100       183 if ($self->has_type) {
78 68 100 100     117 return unless $self->type eq ($other->type // '');
79             }
80             else {
81 29 100       43 return if $other->has_type
82             }
83              
84 73 100       136 return unless $self->optional eq $other->optional;
85              
86 68 100       135 return unless $self->named eq $other->named;
87              
88 63         178 return !!1;
89             }
90              
91             sub is_relaxed_same_interface {
92 98     98 1 167 my ($self, $other) = @_;
93              
94 98 100 100     433 return unless Scalar::Util::blessed($other) && $other->isa('Sub::Meta::Param');
95              
96 96 100       180 if ($self->has_name) {
97 14 100       25 return unless $self->name eq $other->name
98             }
99              
100 91 100       161 if ($self->has_type) {
101 57 100 100     107 return unless $self->type eq ($other->type // '');
102             }
103              
104 71 100       133 return unless $self->optional eq $other->optional;
105              
106 66 100       119 return unless $self->named eq $other->named;
107              
108 61         168 return !!1;
109             }
110              
111             sub is_same_interface_inlined {
112 24     24 1 54 my ($self, $v) = @_;
113              
114 24         30 my @src;
115 24         80 push @src => sprintf("Scalar::Util::blessed(%s) && %s->isa('Sub::Meta::Param')", $v, $v);
116              
117 24 100       55 push @src => $self->has_name ? sprintf("'%s' eq %s->name", $self->name, $v)
118             : sprintf('!%s->has_name', $v);
119              
120 24 100       65 push @src => $self->has_type ? sprintf("'%s' eq (%s->type // '')", "@{[$self->type]}", $v)
  15         33  
121             : sprintf('!%s->has_type', $v);
122              
123 24         78 push @src => sprintf("'%s' eq %s->optional", $self->optional, $v);
124              
125 24         63 push @src => sprintf("'%s' eq %s->named", $self->named, $v);
126              
127 24         1170 return join "\n && ", @src;
128             }
129              
130             sub is_relaxed_same_interface_inlined {
131 30     30 1 62 my ($self, $v) = @_;
132              
133 30         41 my @src;
134 30         79 push @src => sprintf("Scalar::Util::blessed(%s) && %s->isa('Sub::Meta::Param')", $v, $v);
135              
136 30 100       55 push @src => sprintf("'%s' eq %s->name", $self->name, $v) if $self->has_name;
137              
138 30 100       63 push @src => sprintf("'%s' eq (%s->type // '')", "@{[$self->type]}", $v) if $self->has_type;
  21         41  
139              
140 30         125 push @src => sprintf("'%s' eq %s->optional", $self->optional, $v);
141              
142 30         67 push @src => sprintf("'%s' eq %s->named", $self->named, $v);
143              
144 30         710 return join "\n && ", @src;
145             }
146              
147             sub display {
148 66     66 1 78 my $self = shift;
149              
150 66         81 my $s = '';
151 66 100       96 $s .= $self->type if $self->has_type;
152 66 100       184 if ($self->has_name) {
153 10 100       14 $s .= sprintf("%s%s%s",
    100          
154             $self->has_type ? ' ' : '',
155             $self->named ? ':' : '',
156             $self->name);
157             }
158 66         250 return $s;
159             }
160              
161              
162             1;
163             __END__