Рубин,!! оператор (a/k/a двойной удар)

Возможный дубликат:
Что делает!! в рубине?

Привет,

Я новичок в Ruby и не могу найти нигде описание того, что "!!" означает.

Вот пример:

def signed_in?
  !!current_user
end

Если это двойной отрицательный, почему бы не сказать:

def signed_in?
  current_user
end

Пожалуйста, помогите.

Ответ 1

В большинстве языков программирования, включая Ruby, ! будет возвращать противоположное логическому значению операнда. Поэтому, когда вы объединяете два восклицательных знака, они преобразуют значение в логическое.

Ответ 2

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

Если вы что-то отрицаете, это вызывает булевский контекст. Конечно, это также отрицает это. Если вы удвоите его, он заставляет булевский контекст, но возвращает правильное логическое значение.

Например:

"hello"   #-> this is a string; it is not in a boolean context
!"hello"  #-> this is a string that is forced into a boolean 
          #   context (true), and then negated (false)
!!"hello" #-> this is a string that is forced into a boolean 
          #   context (true), and then negated (false), and then 
          #   negated again (true)
!!nil     #-> this is a false-y value that is forced into a boolean 
          #   context (false), and then negated (true), and then 
          #   negated again (false)

В вашем примере метод signed_in? должен возвращать логическое значение (как указано в согласии символом ?). Внутренняя логика, используемая для определения этого значения, - это проверить, установлена ​​ли переменная current_user. Если он установлен, он будет оцениваться до true в булевом контексте. Если нет, он будет оцениваться как ложный. Двойное отрицание заставляет возвращаемое значение быть булевым.

Ответ 3

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

В Ruby вы можете использовать любое значение в инструкции if, например. if current_user будет выполняться, если текущий пользователь не является nil. Большую часть времени это здорово, потому что это позволяет нам печатать явные тесты (например, if !current_user.nil?, длина которых не менее шести символов). Но иногда это может быть действительно запутанным, если вы возвращаете объект, когда метод подразумевает, что он возвращает логическое значение. Методы, чье имя заканчивается на ?, должны возвращать значения правды или фальши, т.е. Они возвращают значение, которое будет оцениваться как true или false. Однако он может стать действительно беспорядочным, если signed_in? возвратил объект пользователя. Например, если вы пытаетесь отладить, почему какой-то код, который использует signed_in?, не работает, вы, вероятно, будете действительно путаться, когда пользовательский объект окажется там, где вы ожидали true или false. В этой ситуации полезно добавить !! до return, поскольку это гарантирует, что значение правды или ложности будет возвращено как true или false.

Ответ 4

Как вы правильно поняли, это двунаправленное использование оператора !. Тем не менее, хотя это может быть сокращенный способ проверить, может ли переменная быть нулевой или нет, ИМО слишком кратки. Взгляните на this и этот пост. Обратите внимание, что в Ruby тестирование чего-то на нуль будет оцениваться как false.