Как я могу отключить предупреждение диализатора при сравнении между переменной модуля и локальной переменной stati c? - PullRequest
1 голос
/ 21 января 2020

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

defmodule Main do
  # -> :demo
  @env Application.get_env(:myproject, :env)

  def run do
    case @env do
      :production -> 1
      _ -> 2
    end
  end
end
lib/myproject/main.ex:6:pattern_match
The pattern can never match the type.

Pattern:
:production

Type:
:demo

Как я могу избежать предупреждения, или я должен каждый раз писать так, как показано ниже?

  def run do
    env = Application.get_env(:myproject, :env)

    case env do
      ...
    end
  end

1 Ответ

2 голосов
/ 21 января 2020

мне каждый раз писать так, как показано ниже?

Это зависит от того, чего вы пытаетесь достичь. dialyzer умный. Атрибутами модуля являются звери времени компиляции , они вычисляются и заменяются везде во время компиляции. В приведенный выше фрагмент кода BEAM входит следующее:

defmodule Main do
  def run do
    case :demo do
      :production -> 1
      _ -> 2
    end
  end
end

При этом dialyzer предупреждает вас о недостижимом утверждении, поскольку он анализирует полученный код со всеми раскрытыми макросами. и атрибуты модуля вставлены.

Если вам нужен другой скомпилированный код в зависимости от среды, у вас есть несколько подходов.

  1. Явно подавляет предупреждение диализатора как описано здесь .
  2. Обдумайте диализатор (примеры могут быть найдены в ядре Elixir , я не буду вставлять их сюда, потому что я не нахожу это решение достаточно надежным.)
  3. Вызовите Application.get_env(:myproject, :env) непосредственно в предложении case (или присвойте локальную переменную, как вы предлагали).

Последний подход - IMSO предпочтительнее .

...