Ответ 1
В большинстве языков программирования, включая Ruby, !
будет возвращать противоположное логическому значению операнда. Поэтому, когда вы объединяете два восклицательных знака, они преобразуют значение в логическое.
Возможный дубликат:
Что делает!! в рубине?
Привет,
Я новичок в Ruby и не могу найти нигде описание того, что "!!" означает.
Вот пример:
def signed_in?
!!current_user
end
Если это двойной отрицательный, почему бы не сказать:
def signed_in?
current_user
end
Пожалуйста, помогите.
В большинстве языков программирования, включая Ruby, !
будет возвращать противоположное логическому значению операнда. Поэтому, когда вы объединяете два восклицательных знака, они преобразуют значение в логическое.
В 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
в булевом контексте. Если нет, он будет оцениваться как ложный. Двойное отрицание заставляет возвращаемое значение быть булевым.
!!
- это просто !
(оператор булевого отрицания), написанный дважды. Это отрицает аргумент, а затем отрицает отрицание. Это полезно, потому что вы можете использовать его для получения логического значения из любого значения. Первый !
преобразует аргумент в логическое, например. 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
.
Как вы правильно поняли, это двунаправленное использование оператора !
. Тем не менее, хотя это может быть сокращенный способ проверить, может ли переменная быть нулевой или нет, ИМО слишком кратки. Взгляните на this и этот пост. Обратите внимание, что в Ruby тестирование чего-то на нуль будет оцениваться как false.