sub count-a {
my $word = "banana";
my $count = 0;
my $foo; # Source of error: $foo intentionally not given a value.
# The value ought to be zero.
while True {
$foo = index $word, "a", $foo;
last unless $foo.defined;
$foo++;
$count++
}
return $count;
}
say count-a;
Is this error message wrong?
Cannot resolve caller index(Str: Str, Any); none of these signatures match:
(Str:D $: Cool:D $needle, *%_)
(Str:D $: Str:D $needle, *%_)
(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
(Str:D $: Str:D $needle, Int:D $pos, *%_)
in sub count-a at scrap.p6 line 11
in block <unit> at scrap.p6 line 18
The error message says index() will accept a third parameter of 'Any', which is what it was given when I verify with $foo.WHAT.
The third parameter of index
is defined as an Int that is actually coerced to Cool
(Cool
being a class that can represent either a number or a string in Perl 6). But the way you have defined it my $foo
(whose type will be "Any") it can't be recognized as any of them. As soon as you give it a value, either "0"
or 0
, that will work.
my $foo = 0;
since the type will be recognized correctly by index
's signature.
So, just to clarify, the error is saying
caller [of subroutine] index [passing params of type] (Str: Str, Any)
cannot be resolved [because it does not match any of] The available index() definitions:
index(Str:D $: Cool:D $needle, *%_)
index(Str:D $: Str:D $needle, *%_)
index(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
index(Str:D $: Str:D $needle, Int:D $pos, *%_)
==========
imho, this error wording will be harder to understand esp. for newbies where it occurs on built-in subroutines due to the thorough use of signature tools such as high order types (e.g. Cool), smilies, $:(whatever that is) and parser internal names such as $needle
maybe could do some magic such as “likely 3rd param caused error as defns require it to be Int:D or Cool:D”
I discuss how we might improve the error message in the second half of this answer. But first:
Is this error message wrong?
Well, you've misunderstood it, so it's wrong in that sense.
The error message says
index()
will accept
To be more precise, the message begins:
Cannot resolve caller
which refers to the index()
call, i.e. not "what index()
will accept" but rather what the code actually asked for which was:
index $word, "a", $foo;
a third parameter of
Any
, which is what it was given when I verify with$foo.WHAT
.
Yes, Any
is the type of the third value of "what it was given", but that refers to the value of the third argument of a call to index()
, not the third parameter of an index()
definition.
The available index()
definitions are:
index(Str:D $: Cool:D $needle, *%_)
index(Str:D $: Str:D $needle, *%_)
index(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
index(Str:D $: Str:D $needle, Int:D $pos, *%_)
None of these four definitions, which have distinct signatures, include a third parameter that will accept the given corresponding third argument in the call, as stored in the call's capture.
Perl 6 culture includes an "awesome error messages" focus, and arguably related confusion has come up before (eg the exchange that led to this comment I made on an earlier SO).
So let's dissect this a little bit further so we can see if we come up with any good ideas for clearly improving the message, or some doc, or whatever.
I think your misunderstanding was rooted in lack of clarity about the distinction between arguments (and calls/captures) and parameters (and definitions/signatures), and particularly your interpretation of this bit of the error message:
index(Str: Str, Any)
The bit after index
looks just like a signature, i.e. it looks like a list of, well, thingies (let's call it the types of "pargs") that would be acceptable to an index()
definition if used in an index()
call.
But it's not a signature, part of an index()
definition. Instead it's actually a list of types corresponding to the list of arguments in an index()
call.
I think this capture analysis and display is specifically constructed to make it easier for the reader of the error message to figure out what went wrong in the attempt to bind the capture to a matching signature.
Unfortunately, while it may now serve that purpose for you if you've understood this answer, we're still left with the problem that your initial interpretation led you to think the error message was just plain wrong -- and others may make the same mistake.
Anyhow, I think that's enough discussion in my answer. If you wish to pursue this please add comments to this answer and/or your question. Does what I've written so far make sense to you? Got any ideas?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With