Skip to content

Commit b1671d9

Browse files
committed
Collect names of multiple erroring parameters
Rather than stop immediately at the first failure, we can be a bit more helpful by collecting up potentially multiple names at once. We limit the list to 5 elements, just to limit the potential output in the case of accidentally passing a list of hundreds or thousands of elements into such a function.
1 parent 2371a9b commit b1671d9

File tree

3 files changed

+70
-15
lines changed

3 files changed

+70
-15
lines changed

pod/perldiag.pod

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4163,9 +4163,12 @@ which is forbidden. See L<perlvar/%{^HOOK}> and L<perlfunc/require EXPR>.
41634163

41644164
=item Missing required named parameter '%s' to subroutine '%s'
41654165

4166-
(F) A subroutine was invoked that uses a signature that declares a
4167-
non-optional named parameter, but the caller did not provide a value associated
4168-
with that name. The caller of the subroutine is presumably at fault.
4166+
=item Missing required named parameters '%s' to subroutine '%s'
4167+
4168+
(F) A subroutine was invoked that uses a signature that declares at least
4169+
one non-optional named parameter, but the caller did not provide a value
4170+
associated with that name. The caller of the subroutine is presumably at
4171+
fault.
41694172

41704173
The message attempts to include the name of the called subroutine. If
41714174
the subroutine has been aliased, the subroutine's original name will be
@@ -7530,10 +7533,12 @@ perl does not recognise the name of the requested attribute.
75307533

75317534
=item Unrecognized named parameter '%s' to subroutine '%s'
75327535

7533-
(F) A subroutine was invoked that uses a signature that declares named parameters but has no
7534-
slurpy parameter, and the caller provided a name that did not
7535-
match any declared named parameter. The caller of the subroutine is
7536-
presumably at fault.
7536+
=item Unrecognized named parameters '%s' to subroutine '%s'
7537+
7538+
(F) A subroutine was invoked that uses a signature that declares named
7539+
parameters but has no slurpy parameter, and the caller provided at least one
7540+
name that did not match any declared named parameter. The caller of the
7541+
subroutine is presumably at fault.
75377542

75387543
The message attempts to include the name of the called subroutine. If
75397544
the subroutine has been aliased, the subroutine's original name will be

pp.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7983,6 +7983,9 @@ PP(pp_multiparam)
79837983
SvPADSTALE_on(PAD_SVl(named->padix));
79847984
}
79857985

7986+
size_t n_errors = 0;
7987+
SV *error_names = NULL;
7988+
79867989
while(argc) {
79877990
SV **svp;
79887991

@@ -8060,22 +8063,48 @@ PP(pp_multiparam)
80608063
hv_store_ent(hv, name, newSVsv(val), 0);
80618064
}
80628065
else {
8063-
// TODO: Consider collecting up all the names of unrecognised
8064-
// in one string
8065-
croak_caller("Unrecognized named parameter '%" UTF8f "' to subroutine '%" SVf "'",
8066-
UTF8fARG(true, namelen, namepv), S_find_runcv_name());
8066+
n_errors++;
8067+
if(!error_names)
8068+
error_names = sv_2mortal(newSVpvs(""));
8069+
if(n_errors <= 5) {
8070+
/* Only bother collecting up the first 5 */
8071+
if(n_errors > 1)
8072+
sv_catpvs(error_names, ", ");
8073+
sv_catpvf(error_names, "'%" UTF8f "'", UTF8fARG(true, namelen, namepv));
8074+
}
80678075
}
80688076
}
80698077

8078+
if(n_errors) {
8079+
if(n_errors > 5)
8080+
sv_catpvs(error_names, ", ...");
8081+
/* diag_listed_as: Unrecognized named parameter '%s' to subroutine '%s' */
8082+
croak_caller("Unrecognized named parameter%s %" SVf " to subroutine '%" SVf "'",
8083+
n_errors > 1 ? "s" : "", SVfARG(error_names), SVfARG(S_find_runcv_name()));
8084+
}
8085+
80708086
for(size_t namedix = 0; namedix < n_named; namedix++) {
80718087
struct op_multiparam_named_aux *named = aux->named + namedix;
80728088
if(!named->is_required || !SvPADSTALE(PAD_SVl(named->padix)))
80738089
continue;
80748090

8075-
// TODO: Consider collecting up all the names of missing
8076-
// parameters in one string
8077-
croak_caller("Missing required named parameter '%" UTF8f "' to subroutine '%" SVf "'",
8078-
UTF8fARG(true, named->namelen, named->namepv), S_find_runcv_name());
8091+
n_errors++;
8092+
if(!error_names)
8093+
error_names = sv_2mortal(newSVpvs(""));
8094+
if(n_errors <= 5) {
8095+
/* Only bother collecting up the first 5 */
8096+
if(n_errors > 1)
8097+
sv_catpvs(error_names, ", ");
8098+
sv_catpvf(error_names, "'%" UTF8f "'", UTF8fARG(true, named->namelen, named->namepv));
8099+
}
8100+
}
8101+
8102+
if(n_errors) {
8103+
if(n_errors > 5)
8104+
sv_catpvs(error_names, ", ...");
8105+
/* diag_listed_as: Missing required named parameter '%s' to subroutine '%s' */
8106+
croak_caller("Missing required named parameter%s %" SVf " to subroutine '%" SVf "'",
8107+
n_errors > 1 ? "s" : "", SVfARG(error_names), SVfARG(S_find_runcv_name()));
80798108
}
80808109
}
80818110

t/lib/croak/signatures

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,30 @@ f(alpha => 123); ## line 4
285285
EXPECT
286286
Missing required named parameter 'beta' to subroutine 'main::f' at - line 4.
287287
########
288+
# NAME multiple missing required named
289+
no warnings 'experimental::signature_named_parameters';
290+
sub f (:$alpha, :$beta) { } ## line 3
291+
f(); ## line 4
292+
EXPECT
293+
Missing required named parameters 'alpha', 'beta' to subroutine 'main::f' at - line 4.
294+
########
288295
# NAME unrecognised named
289296
no warnings 'experimental::signature_named_parameters';
290297
sub f (:$alpha) { } ## line 3
291298
f(alpha => 123, gamma => 456); ## line 4
292299
EXPECT
293300
Unrecognized named parameter 'gamma' to subroutine 'main::f' at - line 4.
301+
########
302+
# NAME multiple unrecognised named
303+
no warnings 'experimental::signature_named_parameters';
304+
sub f (:$alpha) { } ## line 3
305+
f(alpha => 123, gamma => 456, delta => 789); ## line 4
306+
EXPECT
307+
Unrecognized named parameters 'gamma', 'delta' to subroutine 'main::f' at - line 4.
308+
########
309+
# NAME multiple unrecognised named limiting
310+
no warnings 'experimental::signature_named_parameters';
311+
sub f (:$alpha) { } ## line 3
312+
f(alpha => 123, 'a' .. 'z'); ## line 4
313+
EXPECT
314+
Unrecognized named parameters 'a', 'c', 'e', 'g', 'i', ... to subroutine 'main::f' at - line 4.

0 commit comments

Comments
 (0)