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() вызов.

Я думаю, что этот анализ и отображение захвата специально сконструированы так, чтобы читателю сообщения об ошибке было легче выяснить, что пошло не так при попытке связать захват с соответствующей сигнатурой.

К сожалению, хотя теперь он может служить этой цели для вас, если вы поняли этот ответ, у нас все еще остается проблема, заключающаяся в том, что ваша первоначальная интерпретация привела вас к мысли, что сообщение об ошибке было просто неверным - и другие могут сделать то же ошибка.

Во всяком случае, я думаю, что этого достаточно для обсуждения в моем ответе. Если вы хотите продолжить, добавьте комментарии к этому ответу и / или вашему вопросу. Имеет ли смысл то, что я написал до сих пор? Есть идеи?

Другие вопросы по тегам