Что значит!! делать в рубине?

Я использую код, который использует этот синтаксис (спокойная аутентификация).

def logged_in?
  !!current_user()
end

Пробовал поиск по Google, но он просто игнорирует "!!", примет ответ, который может рассказать мне, как найти информацию о поиске строк, таких как!! в google.

Ответ 1

Это двойное отрицание. Первый ! преобразует его в false, если current_user не nil или false. После этого он преобразует его в true. Таким образом, результат всегда является логическим значением, а не значением current_user. Результат всегда true, если current_user не false или nil. В противном случае это false.

Ответ 2

Это оператор отрицания, !, дважды. Это дает значение, имеющее одно и то же значение истинности, но явно только логическое.

В Ruby существует много значений, которые считаются "истинными" (что-либо помимо false и nil), и пара, которая считается "ложной" (как false, так и nil). Первое отрицание преобразует все истинные значения в false, а все ложные значения - в true. Второе отрицание затем отменяет это, оставляя для вас значение, имеющее то же значение истины, что и оригинал, но допускающее только фактические значения true или false.

Это может быть полезно, если вы не хотите, чтобы люди использовали logged_in? как способ доступа к текущему пользователю, но вместо этого вы хотите, чтобы он просто возвращал логическое значение.

Это эквивалентно более явному и подробному:

def logged_in?
  if current_user()
    true
  else
    false
  end
end

Ответ 3

В этой статье используется тот же код:

http://toolmantim.com/articles/bangbang_your_nil_is_dead

В принципе, похоже, что это просто означает применить оператор not (!) дважды - по существу, заставляя метод возвращать true или false вместо true, false или nil.

То есть, если @current_user равно nil, вызов

def logged_in?
  @current_user()
end

вернет нуль. Изменение его (одиночный удар)

def logged_in?
  [email protected]_user()
end

вернет true и изменится далее на (double bang)

def logged_in?
  [email protected]_user()
end

вернет false - что более применимо (и используется), чем nil.

Другой способ написать это:

def logged_in?
  [email protected]_user().nil?
end

но это не распространяется на случай, когда @current_user является ложным, и я думаю, что !! лучше смотреть.