Co oznacza operator znaku zapytania w Ruby?

211

Jaki jest cel operatora znaku zapytania w Ruby?

Czasami wygląda to tak:

assert !product.valid?

czasami jest w ifkonstrukcji.

rtacconi
źródło
2
Znak zapytania na końcu funkcji nie jest operatorem, jest zwykłym znakiem. Znak zapytania wraz z dwukropkiem to trójskładnikowy operator warunkowy. Znak zapytania sam w sobie jest jednoargumentowym operatorem kwotowania. Zobacz stackoverflow.com/questions/16641205/…
Old Pro

Odpowiedzi:

296

Jest to konwencja stylu kodu; wskazuje, że metoda zwraca wartość logiczną.

Znak zapytania jest prawidłowym znakiem na końcu nazwy metody.

chillitom
źródło
9
Dzięki, ale czy ta konwencja oznacza, że ​​działa tylko na logikę, czy mogą wystąpić skutki uboczne? Zabawne, jak to jest hack wokół typowanych języków z typem zwracanym w kodzie.
Jason
5
W tym przypadku jest to wyłącznie konwencja nazewnictwa metod. Nie ma wymuszania boolowskiej wartości zwracanej. To, że nazwa metody kończy się znakiem zapytania, nie oznacza, że ​​metoda musi zwrócić wartość logiczną ... ale zdecydowanie powinna zwrócić wartość logiczną. Istnieje jednak kilka innych zastosowań ?w języku Ruby (jest operatorem potrójnym, przekształcającym znak na jego liczbę całkowitą ASCII, użycie testw wyrażeniach RegEx, itp.), Z których wiele omówiono w innych odpowiedziach tutaj.
Karl Wilbur,
4
@Jason FYI, nawet silnie napisane języki mają takie konwencje. Na przykład, w metodach Java, które zwracają wartość logiczną często są prefiksem „jest”, jak w isEmpty(), isDigit()itp W Ruby, te same metody byłoby napisane empty?, i digit?który jest trochę ładniejszy IMO.
Ajedi32,
3
Ajedi32 - Tak, zgadzam się, że miło jest nazywać takie funkcje, używam iscały czas. To może być bardzo mylące dla kogoś pochodzącego z Swift od znaku zapytania nie jest wykorzystywany do nullable:)
Jason
83

Uwaga: ?wraz ze znakiem zwróci kod znaku ASCII dlaA

Na przykład:

?F # => will return 70

Alternatywnie w Ruby 1.8 możesz:

"F"[0]

lub w ruby ​​1.9:

"F".ord

Zauważ też, że ?Fzwróci ciąg "F", więc aby skrócić kod, możesz również użyć ?F.ordRuby 1.9, aby uzyskać ten sam wynik jak "F".ord.

Greg Osuri
źródło
29
W Ruby 1.9 powróci'F'
zabił
39

W Ruby jest konwencja, że ​​metody zwracające wartości logiczne kończą się znakiem zapytania. Nie ma to większego znaczenia niż to.

Eifion
źródło
28

W twoim przykładzie jest to tylko część nazwy metody. W Ruby możesz także używać wykrzykników w nazwach metod!

Innym przykładem znaków zapytania w Ruby byłby trójskładnikowy operator.

customerName == "Fred" ? "Hello Fred" : "Who are you?"
Andy Gaskell
źródło
13
Aby rozwinąć odpowiedź Andy'ego, zobaczysz także takie rzeczy jak: nazwa_klienta == user.logged_in? ? nazwa.użytkownika: „Kim jesteś?” Zwróć uwagę na podwójny znak zapytania
zapytania
16

W twoim przykładzie

product.valid?

W rzeczywistości jest wywołaniem funkcji i wywołuje funkcję o nazwie valid?. Niektóre typy funkcji „test warunku” / logicznej mają znak zapytania jako część nazwy funkcji zgodnie z konwencją.

Timo Geusch
źródło
41
answer.gsub! (/ function /, 'method')
glenn jackman
15

Warto zauważyć, że ?są dozwolone tylko w nazwach metod, a nie w zmiennych. W procesie uczenia się języka Ruby założyłem, że ?wyznaczyłem boolowski typ zwrotu, więc spróbowałem dodać je do zmiennych flag, co prowadzi do błędów. Doprowadziło mnie to do błędnego uwierzenia przez jakiś czas, że istnieje specjalna składnia dotycząca ?s.

Istotne: Dlaczego nazwa zmiennej nie może kończyć się na `?`, Podczas gdy nazwa metody może?

Rich Smith
źródło
9

Wierzę, że to tylko konwencja dla rzeczy, które są logiczne. Trochę jak powiedzenie „ IsValid”.

Neil Barnwell
źródło
1
zwięzły i niesamowity komentarz specjalnie „Trochę jak powiedzenie„ IsValid ”
Kick Buttowski
2

Jest również używany w wyrażeniach regularnych, co oznacza „co najwyżej jedno powtórzenie poprzedniego znaku”

na przykład wyrażenie regularne /hey?/ pasuje do ciągów „ he” i „ hey”.

José Joel.
źródło
0

Jest to również powszechna konwencja używana z pierwszym argumentem metody testowej z jądra # 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

jak widać w tym pytaniu tutaj

jtzero
źródło
3
To nie jest związane test, ?dto skrót do "d". testprzyjmuje jako pierwszy argument ciąg jednoznakowy, aby można go było wywołać za pomocą test ?d, "/dev"lub test "d", "/dev".
bfontaine