Просто интересно, что !! находится в Ruby.
Что значит!! означает в рубине?
Ответ 1
Не. Он использовался для преобразования значения в логическое значение:
!!nil   #=> false
!!"abc" #=> true
!!false #=> false
Обычно использовать это не нужно, поскольку единственные ложные значения для Ruby - это nil и false, поэтому обычно лучше разрешить это соглашение.
Подумайте об этом как
!(!some_val)
Одна вещь, которая используется для законного действия, - это предотвращение возврата огромного куска данных. Например, вы, вероятно, не хотите возвращать 3MB данных изображения в свой метод has_image?, или вы можете не захотеть вернуть весь объект пользователя в методе logged_in?. Использование !! преобразует эти объекты в простой true/false.
Ответ 2
Он возвращает true, если объект справа не nil, а не false, false, если он nil или false
def logged_in?   
  [email protected]_user
end
Ответ 3
 ! означает отрицание логического состояния, два ! ничего особенного, кроме двойного отрицания.
!true == false
# => true
Обычно используется, чтобы заставить метод возвращать логическое значение. Он обнаружит любую правду, такую как строка, целые числа, а что нет, и превратит ее в логическое.
!"wtf"
# => false
!!"wtf"
# => true
Более реальный вариант использования:
def title
  "I return a string."
end
def title_exists?
  !!title
end
Это полезно, когда вы хотите убедиться, что возвращается логическое значение. ИМХО, это довольно бессмысленно, хотя, видя, что оба if 'some string' и if true - это тот же поток, но некоторые люди считают полезным возвращать логическое значение.
Ответ 4
Обратите внимание, что эта идиома существует и на других языках программирования. C не имел встроенного типа bool, поэтому все булевы были введены как int, а канонические значения 0 или 1. Делает этот пример (скобки добавлены для ясности):
!(1234) == 0
!(0) == 1
!(!(1234)) == 1
Синтаксис "не-не" преобразует любое ненулевое целое число в 1, каноническое логическое истинное значение.
В общем, я считаю гораздо лучше провести разумное сравнение, чем использовать эту необычную идиому:
int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious
Ответ 5
Это полезно, если вам нужно сделать эксклюзивную или. Копирование с Мэтта ван Хорна отвечает небольшими изменениями:
1 ^ true
TypeError: can't convert true into Integer
!!1 ^ !!true
=> false
Я использовал его для обеспечения того, чтобы две переменные имели либо нуль, либо оба не ноль.
raise "Inconsistency" if !!a ^ !!b
Ответ 6
Это "двойной отрицательный", но практика не поощряется. Если вы используете rubocop, вы увидите, что он жалуется на такой код с нарушением Style/DoubleNegation.
В аргументе говорится:
Поскольку это и загадочно и обычно избыточно, его следует избегать [затем перефразировать:] Измените
!!somethingна!something.nil?
Ответ 7
Понимание того, как это работает, может быть полезно, если вам нужно преобразовать, скажем, перечисление в логическое. У меня есть код, который делает именно это, используя classy_enum gem:
class LinkStatus < ClassyEnum::Base
  def !
    return true
  end
end
class LinkStatus::No < LinkStatus
end
class LinkStatus::Claimed < LinkStatus
  def !
    return false
  end
end
class LinkStatus::Confirmed < LinkStatus
  def !
    return false
  end
end
class LinkStatus::Denied < LinkStatus
end
Тогда в служебном коде у меня есть, например:
raise Application::Error unless !!object.link_status   # => raises exception for "No" and "Denied" states.
Фактически оператор bangbang стал тем, что я мог бы написать в качестве метода, называемого to_bool.
