Что означает оператор вопросительного знака в Ruby?


211

Какова цель оператора вопросительного знака в Ruby?

Иногда это выглядит так:

assert !product.valid?

иногда это в ifконструкте.


2
Вопросительный знак в конце функции - это не оператор, а обычный символ. Вопросительный знак наряду с двоеточием является троичным условным оператором. Вопросительный знак сам по себе является унарным оператором кавычек. См. Stackoverflow.com/questions/16641205/…
Old Pro

Ответы:


296

Это соглашение о стиле кода; это указывает, что метод возвращает логическое значение.

Знак вопроса является допустимым символом в конце имени метода.


9
Спасибо, но означает ли это соглашение, что это только логика или могут быть побочные эффекты? Забавно, что это своего рода хакерство вокруг типизированных языков с типом возврата в коде.
Джейсон

5
В этом случае это строго соглашение об именовании методов. Нет принудительного применения логического возвращаемого значения. Тот факт, что имя метода заканчивается знаком вопроса, не означает, что метод должен возвращать логическое значение ... но он определенно должен возвращать логическое значение. Однако есть несколько других применений ?в Ruby (это троичный оператор, преобразующий символ в его целое ASCII, использование в test, в RegEx и т. Д.), Многие из которых описаны в других ответах здесь.
Карл Уилбур

4
@Jason FYI, даже в строго типизированных языках есть такие соглашения. Например, в методах Java , которые возвращают логическое значение , часто с префиксом «является», как isEmpty(), isDigit()и т.д. В рубин, одни и те же методы были бы написаны empty?, и digit?что совсем немного лучше ИМО.
Ajedi32

3
Ajedi32 - Да, я согласен, что приятно называть такие функции, я использую isвсе время. Это может быть очень запутанным для кого - то наступающем из Swift с вопросительным знаком там используется для nullable:)
Jason

83

Также обратите внимание, ?вместе с символом, вернет код символа ASCII дляA

Например:

?F # => will return 70

Поочередно в ruby ​​1.8 вы можете сделать:

"F"[0]

или в рубине 1.9:

"F".ord

Также обратите внимание, что ?Fбудет возвращена строка "F", поэтому, чтобы сделать код короче, вы также можете использовать ?F.ordв Ruby 1.9, чтобы получить тот же результат, что и "F".ord.


29
В ruby ​​1.9 он вернется'F'
klew

39

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


28

В вашем примере это только часть имени метода. В Ruby вы также можете использовать восклицательные знаки в именах методов!

Другим примером вопросительных знаков в Ruby может быть троичный оператор.

customerName == "Fred" ? "Hello Fred" : "Who are you?"

13
Чтобы расширить ответ Энди, вы также увидите такие вещи, как: customerName == user.logged_in? ? user.name: "Кто ты?" Обратите внимание на двойной знак вопроса
Вопросительный знак

17

В вашем примере

product.valid?

На самом деле это вызов функции и вызывает функцию с именем valid?. Некоторые типы «проверки состояния» / булевых функций имеют условный знак как часть имени функции.


41
answer.gsub! (/ function /, 'method')
Гленн Джекман

15

Возможно, стоит отметить, что ?s допускаются только в именах методов, а не в переменных. В процессе изучения Ruby я предполагал, что ?это булев тип возвращаемого значения, поэтому я попытался добавить их в переменные флага, что привело к ошибкам. Это привело меня к тому, что какое-то время я ошибочно полагал, что существует какой-то особый синтаксис с использованием ?s.

Соответствующий: Почему имя переменной не может заканчиваться на `?`, А имя метода может?


9

Я считаю, что это просто соглашение для вещей, которые являются булевыми. Немного как сказать " IsValid".


1
краткий и удивительный комментарий специально "Немного похоже на высказывание" IsValid "
Kick Buttowski

2

Он также используется в регулярных выражениях, что означает «не более одного повторения предыдущего символа»

например, регулярное выражение /hey?/ совпадает со строками " he" и " hey".


0

Это также общее соглашение для использования с первым аргументом метода test из Kernel # test

irb(main):001:0> test ?d, "/dev" # directory exists?
=> true
irb(main):002:0> test ?-, "/etc/hosts", "/etc/hosts" # are the files identical
=> true

как видно из этого вопроса здесь


3
Это не связано с test, ?dэто ярлык для "d". testпринимает в качестве первого аргумента строку из одного символа, поэтому вы можете вызвать ее с помощью test ?d, "/dev"или test "d", "/dev".
bfontaine
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.