O que o operador de ponto de interrogação significa em Ruby?

211

Qual é o objetivo do operador de ponto de interrogação no Ruby?

Às vezes, aparece assim:

assert !product.valid?

às vezes está em uma ifconstrução.

rtacconi
fonte
2
O ponto de interrogação no final de uma função não é um operador, é um caractere comum. O ponto de interrogação junto com dois pontos é um operador condicional ternário. O ponto de interrogação por si só é um operador de cotação unário. Veja stackoverflow.com/questions/16641205/…
Old Pro

Respostas:

296

É uma convenção de estilo de código; indica que um método retorna um valor booleano.

O ponto de interrogação é um caractere válido no final de um nome de método.

chillitom
fonte
9
Obrigado, mas essa convenção significa apenas a lógica ou poderia haver efeitos colaterais? Engraçado como isso é uma espécie de hack nos idiomas digitados com o tipo de retorno no código.
21412 Jason
5
Nesse caso, é estritamente uma convenção de nomenclatura de métodos. Não há imposição de um valor de retorno booleano. Só porque o nome do método termina em um ponto de interrogação não significa que o método deve retornar um booleano ... mas, definitivamente, deve retornar um booleano. No entanto, existem vários outros usos do ?in Ruby (é um operador ternário, convertendo um caractere em seu número inteiro ASCII, uso testem RegEx'es etc.), muitos dos quais são abordados nas outras respostas aqui.
Karl Wilbur
4
@ Jason FYI, mesmo os idiomas fortemente tipados têm convenções como essa. Por exemplo, em métodos Java que retornam um valor booleano muitas vezes são prefixados com "é", como em isEmpty(), isDigit()etc. Em Ruby, os mesmos métodos seria escrito empty?, e digit?que é um pouco mais agradável IMO.
Ajedi32
3
Ajedi32 - Sim, eu concordo que é bom nomear funções assim, eu uso iso tempo todo. Isso pode ser super confuso para alguém vindo de Swift desde o ponto de interrogação não é usado para nullable:)
Jason
83

Observe também que, ?juntamente com um caractere, retornará o código de caractere ASCII paraA

Por exemplo:

?F # => will return 70

Como alternativa no ruby ​​1.8, você pode:

"F"[0]

ou em ruby ​​1.9:

"F".ord

Observe também que ?Fretornará a string "F"; portanto, para tornar o código mais curto, você também pode usar ?F.ordno Ruby 1.9 para obter o mesmo resultado que "F".ord.

Greg Osuri
fonte
29
Em Ruby 1.9 retornará'F'
klew
39

É uma convenção em Ruby que os métodos que retornam valores booleanos terminem em um ponto de interrogação. Não há mais significado para isso do que isso.

Eifion
fonte
28

No seu exemplo, é apenas parte do nome do método. No Ruby, você também pode usar pontos de exclamação nos nomes dos métodos!

Outro exemplo de pontos de interrogação no Ruby seria o operador ternário.

customerName == "Fred" ? "Hello Fred" : "Who are you?"
Andy Gaskell
fonte
13
Para expandir a resposta de Andy, você também verá coisas como: customerName == user.logged_in? ? user.name: "Quem é você?" Observe o ponto de interrogação dupla
Ponto de Interrogação
16

No seu exemplo

product.valid?

É realmente uma chamada de função e chama uma função chamada valid?. Certos tipos de "teste para condição" / funções booleanas têm um ponto de interrogação como parte do nome da função por convenção.

Timo Geusch
fonte
41
(Resolvido) (/ function /, 'method')
glenn jackman
15

Vale a pena ressaltar que ?s são permitidos apenas nos nomes dos métodos, não nas variáveis. No processo de aprendizado de Ruby, assumi que ?designava um tipo de retorno booleano, então tentei adicioná-los a variáveis ​​de flag, levando a erros. Isso me levou a acreditar erroneamente por um tempo que havia alguma sintaxe especial envolvendo ?s.

Relevante: Por que um nome de variável não pode terminar com `?` Enquanto um nome de método pode?

Rich Smith
fonte
9

Eu acredito que é apenas uma convenção para coisas que são booleanas. Um pouco como dizer " IsValid".

Neil Barnwell
fonte
1
conciso e comentário incrível especialmente "um pouco como dizer 'IsValid'
pontapé Buttowski
2

Também é usado em expressões regulares, significando "no máximo uma repetição do caractere anterior"

por exemplo, a expressão regular /hey?/ corresponde às cadeias " he" e " hey".

José Joel.
fonte
0

Também é uma convenção comum usar com o primeiro argumento do método de teste do 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

como visto nesta pergunta aqui

jtzero
fonte
3
Não está relacionado a test, ?dé um atalho para "d". testusa uma string de um caractere como seu primeiro argumento, para que você possa chamá-la com test ?d, "/dev"ou test "d", "/dev".
precisa saber é o seguinte