index () сообщение об ошибке неверно для третьего параметра? - PullRequest
0 голосов
/ 04 мая 2018
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 ]

0 голосов
/ 05 мая 2018

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

Это сообщение об ошибке неверно?

Ну, вы неправильно поняли, так что это неправильно в этом смысле.

В сообщении об ошибке говорится, что 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 выглядит как подпись , то есть он выглядит как список, ну, штук (давайте назовем его типами "pargs"), которые были бы приемлемы для определения index(), если они используются в вызове index().

Но это не подпись, часть определения index(). Вместо этого это фактически список типов, соответствующих списку аргументов в вызове index().

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

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

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

0 голосов
/ 06 мая 2018

Итак, просто чтобы уточнить, ошибка говорит:

вызывающий абонент [подпрограммы] индекс [передаваемые параметры типа] (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»

0 голосов
/ 04 мая 2018

Третий параметр index определяется как Int, который фактически приводится к Cool (Cool является классом , который может представлять число или строку в Perl 6 ). Но так, как вы его определили my $foo (тип которого будет «Любой»), он не может быть распознан как любой из них. Как только вы дадите ему значение, "0" или 0, оно будет работать.

my $foo = 0;  

, поскольку тип будет правильно распознаваться по подписи index.

...