index() сообщение об ошибке неверно для третьего параметра?
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;
Это сообщение об ошибке неверно?
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
В сообщении об ошибке говорится, что index() примет третий параметр "Any", то есть тот, который был задан, когда я проверяю с помощью $foo.WHAT.
3 ответа
Третий параметр index
определяется как Int, который на самом деле приводится к Cool
(Cool
будучи классом, который может представлять число или строку в Perl 6). Но так, как вы это определили my $foo
(чей тип будет "Любой"), он не может быть распознан как любой из них. Как только вы дадите ему значение, либо "0"
или же 0
, Это будет работать.
my $foo = 0;
так как тип будет правильно распознан index
подпись.
Так что, чтобы уточнить, ошибка говорит
индекс вызывающего абонента [подпрограммы] [передача параметров типа] (Str: Str, Any)
не может быть решен [потому что он не соответствует ни одному из] Доступные определения index():
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, эту формулировку ошибки будет сложнее понять esp. для новичков, где это происходит во встроенных подпрограммах из-за тщательного использования инструментов подписи, таких как высокоуровневые типы (например, Cool), смайлики, $:(, что бы это ни было) и внутренние имена синтаксического анализатора, такие как $needle
Может быть, может сделать что-то магическое, например, "вероятно, 3-й параметр вызвал ошибку, поскольку defns требует, чтобы она была Int:D или Cool:D"
Я обсуждаю, как мы могли бы улучшить сообщение об ошибке во второй половине этого ответа. Но сначала:
Это сообщение об ошибке неверно?
Ну, вы неправильно поняли, так что это неправильно в этом смысле.
Сообщение об ошибке говорит
index()
приму
Чтобы быть более точным, сообщение начинается:
Cannot resolve caller
что относится к index()
звоните, т.е. не "что" index()
примет "а скорее то, что код на самом деле просил, который был:
index $word, "a", $foo;
третий параметр
Any
это то, что было дано, когда я проверяю с$foo.WHAT
,
Да, Any
это тип третьего значения "что было дано", но это относится к значению третьего аргумента вызова index()
, а не третий параметр index()
определение.
Доступные index()
определения:
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, *%_)
Ни одно из этих четырех определений, имеющих разные сигнатуры, не включает третий параметр, который будет принимать данный соответствующий третий аргумент в вызове, сохраненный в перехвате вызова.
Идеи о том, как улучшить сообщение об ошибке
Культура Perl 6 включает в себя фокус "удивительных сообщений об ошибках", и, возможно, возникла путаница, связанная с этим (например, обмен, который привел к этому комментарию, который я сделал в более ранней версии SO).
Итак, давайте разберемся с этим немного дальше, чтобы мы могли увидеть, найдем ли мы какие-нибудь хорошие идеи для четкого улучшения сообщения, какой-нибудь документ или что-то еще.
Я думаю, что ваше недоразумение коренится в отсутствии ясности в отношении различия между аргументами (и вызовами / перехватами) и параметрами (и определениями / сигнатурами), и особенно вашей интерпретацией этого бита сообщения об ошибке:
index(Str: Str, Any)
Немного после index
выглядит так же, как подпись, то есть выглядит как список штук (ну, назовем это типами "паргов"), которые были бы приемлемы для index()
определение, если используется в index()
вызов.
Но это не подпись, а часть index()
определение. Вместо этого это на самом деле список типов, соответствующих списку аргументов в index()
вызов.
Я думаю, что этот анализ и отображение захвата специально сконструированы так, чтобы читателю сообщения об ошибке было легче выяснить, что пошло не так при попытке связать захват с соответствующей сигнатурой.
К сожалению, хотя теперь он может служить этой цели для вас, если вы поняли этот ответ, у нас все еще остается проблема, заключающаяся в том, что ваша первоначальная интерпретация привела вас к мысли, что сообщение об ошибке было просто неверным - и другие могут сделать то же ошибка.
Во всяком случае, я думаю, что этого достаточно для обсуждения в моем ответе. Если вы хотите продолжить, добавьте комментарии к этому ответу и / или вашему вопросу. Имеет ли смысл то, что я написал до сих пор? Есть идеи?