Как бы вы запомнили розу с помощью Sorbet? - PullRequest
3 голосов
/ 20 июня 2019

Пытаясь аннотировать этот код, памятка розы (@||=) выдает мне ошибку Use of undeclared variable @git_sha.

# typed: strict
# frozen_string_literal: true

module Util
  extend T::Sig

  sig { returns(String) }
  def self.git_sha
    @git_sha ||= ENV.fetch(
      'GIT_REV',
      `git rev-parse --verify HEAD 2>&1`
    ).chomp
  end
end

Насколько я обнаружил, я должен объявить тип переменной с помощью T.let но не выяснили как конкретно.

1 Ответ

3 голосов
/ 21 июня 2019

Здесь есть пара решений.

  1. Инициализируйте переменную экземпляра вне метода и присвойте ей аннотацию типа:
# typed: strict
# frozen_string_literal: true

module Util
  extend T::Sig

  @git_sha = T.let(nil, T.nilable(String))

  sig { returns(String) }
  def self.git_sha
    @git_sha ||= ENV.fetch(
      'GIT_REV',
      `git rev-parse --verify HEAD 2>&1`
    ).chomp
  end
end

→ Посмотреть на sorbet.run

Это предпочтительное решение. Концептуально, у этого класса есть две фазы выполнения: когда он инициализируется и когда он используется. Если переменной экземпляра не дана аннотация типа, когда она инициализируется в Sorbet, она будет везде T.untyped (или ошибка в # typed: strict). Потому что, если он не аннотирован при инициализации, Сорбет не может знать, какой путь к коду может сначала записаться в это местоположение. (Даже в этом случае, когда есть одно местоположение, Сорбет не проводит такого глобального анализа.)

  1. Используйте другой уровень строгости .

Документы по уровням строгости .

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

...