Проверка правдивости в страже - PullRequest
0 голосов
/ 25 сентября 2019

Я могу использовать охранники, чтобы проверить, является ли аргумент true:

defmodule Truth do
  def true?(term) when term, do: "#{term} is true"
  def true?(term), do: "#{term} is not true"
end

Это работает, как и ожидалось, для логических значений:

Truth.true?(true)
#=> "true is true"
Truth.true?(false)
#=> "false is not true"

Но это не может быть проверено на достоверность:

Truth.true?(1)
#=> "1 is not true"

Можно ли проверить на правдивость охранников?Например, может ли следующая функция быть написана с использованием охранников в стиле true?/1 выше?

def truthy?(term) do
  if term, do: "#{term} is truthy", else: "#{term} is falsey"
end

1 Ответ

3 голосов
/ 25 сентября 2019

Согласно официальной документации для Стражей :

Страж начинается с ключевого слова when, за которым следует логическое выражение.

Таким образом, выражения в охранниках должны быть логическими выражениями.

Истина в эликсире определяется такими макросами, как if/2.Эти макросы недоступны внутри защиты, поэтому нам нужен другой способ преобразования терминов в логические значения.

Из документации (и реализация ) if/2 видно, что определениеИстина заключается в том, что false и nil являются ложными, все остальное является правдой.Таким образом, мы можем использовать это для реализации наших защитников правдивости:

defmodule Truth do
  defguard is_falsey(term) when term in [false, nil]
  defguard is_truthy(term) when not is_falsey(term)

  def truthy?(foo) when is_truthy(foo), do: "#{foo} is truthy"
  def truthy?(foo), do: "#{foo} is falsey"
end

Это тогда работает как ожидалось:

Truth.truthy?(true)
#=> "true is truthy"
Truth.truthy?(1)
#=> "1 is truthy"
Truth.truthy?(false)
#=> "false is falsey"
Truth.truthy?(nil)
#=> " is falsey"
...