Spec-Zone.ru › Homebrew

Проверка типов с Sorbet

Большая часть кода в Homebrew написана на Ruby, который является динамическим языком. Для получения преимуществ статической проверки типов мы установили Sorbet в нашем коде, что обеспечивает преимущества статической проверки типов для динамических языков, таких как Ruby.

Документация Sorbet — хорошее место для начала, если вы хотите углубиться в Sorbet и его возможности.

Sorbet в кодовой базе Homebrew

Встроенные аннотации типов

Чтобы добавить аннотации типов к классу или модулю, нам нужно сначала расширить его модулем T::Sig (читаем как Type::Signature). Это добавляет метод sig, который используется для аннотации сигнатур методов. Вот простой пример:

class MyClass
  extend T::Sig

  sig { params(name: String).returns(String) }
  def my_method(name)
    "Hello, #{name}!"
  end
end

С помощью params, мы указываем, что у нас есть параметр name, который должен быть типа String, а с помощью returns, мы указываем, что этот метод всегда возвращает значение типа String.

Для получения дополнительной информации о том, как выразить более сложные типы, обратитесь к официальной документации:

  • Сигнатуры методов
  • Типы классов
  • Типы с возможностью nil
  • Объединение типов

Файлы интерфейсов Ruby (.rbi)

Файлы RBI помогают Sorbet узнать о константах, предках и методах, определенных способами, которые он не понимает напрямую. Мы также можем создать файл RBI, чтобы помочь Sorbet понять динамические определения.

Иногда необходимо явно включить модуль Kernel, чтобы Sorbet знал, что такие методы, как puts, доступны в данном контексте. Это в основном необходимо для модулей, поскольку они могут использоваться как в BasicObject (которые не включают Kernel) так и в Object (которые включают Kernel по умолчанию). В этом случае необходимо создать файл .rbi (пример), так как повторное включение модуля Kernel в сам код может привести к проблемам.

Дополнительную информацию о файлах RBI вы найдете здесь.

Директория Library/Homebrew/sorbet

  • Директория rbi содержит все файлы Ruby Interface (.rbi) автоматически сгенерированные запуском brew typecheck --update.

    • Файлы RBI для всех жемчужин создаются с помощью Tapioca.
    • Определения для динамического кода (т.е. метапрограммирование) генерируются с помощью srb rbi hidden-definitions.
    • Определения для отсутствующих констант генерируются с помощью srb rbi todo.
  • Файл config — это список аргументов, разделенных символом новой строки, которые нужно передать srb tc, так же как если бы они были переданы в командной строке. Аргументы в файле конфигурации всегда передаются первыми, а затем — аргументы, предоставленные в командной строке. Мы используем его для игнорирования директорий жемчужин, которые мы не хотим проверять на типы.

  • Каждый файл Ruby в кодовой базе имеет магический комментарий # typed: <level> вверху, где <level> — один из уровней строгости Sorbet, обычно false, true или strict. Файлы false сообщают только об ошибках, связанных с синтаксисом, разрешением констант и корректностью сигнатур методов, но не о типе ошибок. Наша долгосрочная цель — перенести все файлы false в true и начать сообщать о типах ошибок в этих файлах тоже. Поэтому при добавлении новых файлов вы должны по возможности пометить его как # typed: true и разобраться с возникшими ошибками типов.

Использование brew typecheck

При запуске без аргументов brew typecheck будет работать, принимая во внимание уровни строгости, заданные в каждом из отдельных файлов Ruby в основной кодовой базе Homebrew. Однако, при запуске на конкретном файле или директории, может отображаться больше ошибок, так как Sorbet не может разрешить константы, определённые за пределами указанного файла. Эти проблемы могут быть решены с помощью файлов RBI. В настоящее время brew typecheck предоставляет опции --quiet, --file, --dir и --ignore, но вы можете изучить больше вариантов с помощью srb tc --help и передать их с srb tc.

Решение ошибок типов

Sorbet сообщает об ошибках типов вместе с кодом ссылки на ошибку, который можно использовать для поиска дополнительной информации о том, как отладить ошибку или что вызывает ошибку в Документации Sorbet. Вот как отладить некоторые распространённые ошибки типов:

  • Использование T.reveal_type. В файлах, которые имеют уровень строгости true или выше, если мы обернём вызов переменной или метода в T.reveal_type, Sorbet покажет нам, какой тип он считает, что имеет эта переменная, в выводе srb tc. Это особенно полезно при написании сигнатур методов и отладке. Убедитесь, что вы удалите эту строку из своего кода перед добавлением изменений, так как это всего лишь инструмент отладки.

  • Одной из наиболее частых ошибок, с которой мы столкнулись, является 7003: Method does not exist.. Поскольку Ruby — очень динамичный язык, методы могут быть определены способами, которые Sorbet не может увидеть статически. В таких случаях проверьте, существует ли метод во время выполнения, если нет, то Sorbet поймал будущую ошибку! Но также возможно, что, хотя метод существует во время выполнения, Sorbet не может его увидеть. В таких случаях мы используем файлы .rbi.

  • Поскольку Sorbet не предполагает автоматического включения Kernel в модули, при попытке использовать методы, такие как puts, ohai, odebug и т.д., могут возникнуть многочисленные ошибки. Простым решением этой проблемы является добавление дополнительной строки include Kernel в соответствующий файл RBI.

  • Советы выше очень общие и применимы во многих случаях. Для некоторых распространённых ловушек при работе с Sorbet обратитесь к Справочнику по ошибкам Sorbet и FAQ.

© 2009–present Homebrew contributors
Licensed under the BSD 2-Clause License.
https://docs.brew.sh/Typechecking

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API