Я реализую crash
функцию в GenServer
, чтобы проверить поведение супервизора и реестра, которые будут управлять этим процессом.Работа выполняется в Elixir, но я полагаю, что это также может касаться Эрланга.
Я мог бы назвать raise()
, но сначала я применил 1/0
в качестве причины сбоя.Компилятор, будучи умным парнем, для следующего кода:
def handle_cast(:crash, state) do
a = 1 / 0
{:noreply, state}
end
Я получил предупреждение:
warning: this expression will fail with ArithmeticError
lib/xyz/worker.ex:47
Справедливо.В конце концов, даже старые компиляторы C или C ++ могли обнаруживать подобные вещи.Я попробовал библиотечный вызов, заменив a = 1 / 0
на a = 1 / :math.sin(0)
.То же предупреждение.Мое любопытство проснулось, и я попробовал разные вещи с одинаковым результатом.На самом деле, похоже, что это не так легко обмануть компилятор!В конце концов, я добавил:
a = 1 / Enum.reduce([0, 1, -1], 0, fn(n, acc) -> n+acc end)
и получил другое предупреждение:
warning: the result of the expression is ignored (suppress the warning by assigning the expression to the _ variable)
lib/xyz/worker.ex:50
строка 50: a = 1 / Enum.reduce(...)
.
Я потратил пару часов, пытаясь по-другомувещи с всегда получать либо предупреждение.
Я полагаю, что первое поднято, потому что компилятор может предварительно вычислить результат из константных аргументов, типа функции и встроенной в конечном итоге операции 1 / 0
.
Все же я не понимаю второе предупреждение.В одном из тестов я написал:
def handle_cast(:crash, state) do
a = 1 / Enum.reduce([0, 1, -1], 0, fn(n, acc) -> n+acc end)
# {:noreply, state}
end
, который фактически подавляет предупреждение, но я действительно не понимаю, почему.
NB.1 : версии:
maurice@mickey> elixir -v
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Elixir 1.6.1 (compiled with OTP 19)
NB.2 : Мне известен этот вопрос , но я не думаю, что ответ здесь применим.
Пока я буду звонить raise(...)
...