Пробег диализера после аннотации с Тайпером не показал никаких предупреждений

StackOverflow https://stackoverflow.com/questions/5849335

  •  27-10-2019
  •  | 
  •  

Вопрос

В проекте с около 6000 строк кода Erlang, но без типа -spec() Аннотация еще я попробовал следующее:

typer --annotate *.erl

Я заменил все *.erl файлы с аннотированными и запускались

dialyzer --src -c *.erl

Я ожидал получить много предупреждений (запустил комбинацию Dialyzer/Typer в первый раз), но после того, как все сообщили, что все диализеры сообщили, что 2 старых вызовов в User_default, которые не существуют.

Никакие другие предупреждения по умолчанию не вызвали.

Я сделал ошибку, используя это или такой обычный результат?

Это комбинация автоматической аннотации с typer а также dialyzer Не так полезно или мне просто повезло, и у моего кода нет проблем?


Sidenote: Мне пришлось прокомментировать 3 или 4 -spec()s Потому что dialyzer разбился на них.

Я использую Dialyzer V2.2.0 и Typer версию V0.1.7.4 от Erlang R13B04

Это было полезно?

Решение

В качестве побочного эффекта сообщений об ошибке в списке Erlang-Bugs я получил подробный ответ на это от Kostis Sagonas, изобретателя Dialyzer и Typer.

На мой боковой вопрос я получил следующий отличный и подробный ответ:

На солнце, 1 мая 2011 года в 17:53, Костис Сагонас написал:

Пир Стритцингер написал:

Кстати: нормально ли не получить никаких предупреждений, когда это просто делать -аннотировать в Тайпере, а затем диализер без вручную

Да. Фактически, Тайпер - это всего лишь передняя часть для базового вывода диализатора (т.е. без компонента идентификации предупреждения).

ИМО, в этом не так мало, если вы не намереваетесь вручную «массаж» тех спецификаций, которые вы получаете, и предоставить больше информации для некоторых из них. Взгляните на свою предыдущую программу. Тот факт, что два <:64,: _*8 >> Типы относились к тому же количеству, что можно было бы выразить лучше, если вы представили тип, как в:

  -type packet() :: <<_:64,_:_*8>>,

Точно так же для канала:

  -type channel() :: atom() | pid() |{atom(),_}.

И тогда спецификация уже будет выглядеть лучше. Кроме того, Dialyzer/Typer не имеет информации о том, какой тип веселья вы собираетесь использовать во втором аргументе функции recv/3 но ты делаешь! Из кода ясно, что он занимает #can_pkt{} Запись, так почему бы вам не добавить подходящие типы в его поля и не представить для него тип?

  -record(can_pkt, {id :: id(), data :: binary(), timestamp :: ts()}).
  -type can_pkt() :: #can_pkt{}.

тогда спецификации могут выглядеть намного лучше:

  -spec recv(packet(), fun((can_pkt()) -> R), channel()) -> R.
  -spec decode(packet()) -> can_pkt().

и обратите внимание, что я использовал переменную типа заполнителя R обозначать тот факт, что функционирует recv/2 Возвращает любой тип, веселье во втором аргументе возвращается. Вы, вероятно, знаете, что это за тип, поэтому вы также должны представить для него тип и использовать его правильное имя.

Надеюсь это поможет,

Костис

Пса Жаль, что вы опубликовали это в Erlang-Bugs, так как информация, содержащаяся в вышеизложенном, является более интересной, чем фактическая ошибка.

Поскольку он ссылается на фрагмент кода, я включил в свой отчет об ошибках, я включаю его здесь. Следующий фрагмент кода был автоматически аннотирован typer --annotate:

-record(can_pkt, {id, data, timestamp}).

-spec recv(<<_:64,_:_*8>>,fun((_) -> 
      any()),atom() | pid() | {atom(),_}) -> any().

recv(Packet, Recv_fun, Chan) ->
    P = decode(Packet),
    #can_pkt{id=Can_id, data=Can_data}=P,
    Recv_fun(P).

-spec decode(<<_:64,_:_*8>>) -> 
      #can_pkt{id::<<_:11>>,data::binary(),timestamp::char()}.

decode(<<_:12, Len:4, Timestamp:16,
        0:3, Id:11/bitstring, 0:18,
        Data:Len/binary, _/binary>>) ->
    #can_pkt{id=Id, data=Data, timestamp=Timestamp}.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top