Jaki jest cel znaku „!” i "?" na końcu nazw metod?

Odpowiedzi:

160

Dla czytelności to „tylko cukierkowa powłoka”, ale mają one wspólne znaczenie:

  • Metody kończące się !wprowadzeniem trwałej lub potencjalnie niebezpiecznej zmiany ; na przykład:
    • Enumerable#sortzwraca posortowaną wersję obiektu, Enumerable#sort!sortując go w miejscu.
    • W Railsach ActiveRecord::Base#savezwraca wartość false, jeśli zapisywanie się nie powiodło, podczas gdy ActiveRecord::Base#save!wywołuje wyjątek.
    • Kernel::exitpowoduje zakończenie działania skryptu, podczas gdy Kernel::exit!robi to natychmiast, pomijając wszelkie programy obsługi wyjścia.
  • Metody kończące się ?zwracają wartość logiczną , co sprawia, że ​​kod płynie jeszcze bardziej intuicyjnie jak zdanie - if number.zero?brzmi jak „jeśli liczba wynosi zero”, ale if number.zeropo prostu wygląda dziwnie.

W twoim przykładzie name.reversezwraca odwrócony ciąg znaków, ale zmienna faktycznie zawiera odwróconą nazwę dopiero po name.reverse!wierszu . wygląda na to, że „czy dane binarne?”.namename.is_binary_data?name

jtbandes
źródło
22
Jedną z ważnych uwag jest to, że powinieneś mieć metodę huk tylko wtedy, gdy masz również odpowiednią metodę bez huku. Huk służy do odróżnienia „bardziej zaskakującej” wersji metody od „mniej zaskakującej”. Jeśli masz tylko jedną metodę, nie ma potrzeby rozróżniania i nie powinieneś nazywać jej z hukiem. Zobacz Array#clearna przykład. Czyści tablicę. Wyczyszczenie tablicy powoduje jej naturalną mutację. Nie ma w tym nic dziwnego, nazwa już to wyjaśnia, dlatego: bez huku. Zobacz ruby-forum.com/topic/176830#773946 .
Jörg W Mittag
2
Dodając do tego, co powiedział @ JörgWMittag, zgodnie z Przewodnikiem po stylu Ruby : Nazwy potencjalnie niebezpiecznych metod (tj. Metod, które modyfikują siebie lub argumenty, zakończ! (Nie uruchamia finalizatorów jak exit) itp.) Powinny kończyć się wykrzyknik, jeśli istnieje bezpieczna wersja tej niebezpiecznej metody .
Tod Birdsall
2
Uważaj, nie zawsze tak jest. Na przykład Ruby Array # concat docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat . Tam, gdzie można się poważnie spalić, jest coś takiego jak MyActiveRecordModel.column_names.concat (...). Zamiast tego musisz go sklonować przed wykonaniem konkatacji.
wintondeshong
8

W Rubim ?oznacza, że ​​metoda zwróci wartość logiczną i !zmodyfikuje obiekt, na którym została wywołana. Są po to, aby poprawić czytelność podczas przeglądania kodu.

J Lundberg
źródło
5

W przeciwieństwie do - jak sądzę - większości języków programowania ...

Ruby, metody mogą kończyć się znakami zapytania lub wykrzyknikami.

Zgodnie z konwencją metody odpowiadające na pytania (tj. Tablica # pusta? Zwraca prawdę, jeśli odbiorca jest pusty) kończą się znakami zapytania.

Potencjalnie „niebezpieczne” metody (tj. Metody, które modyfikują siebie lub argumenty, wyjście! Itp.) Zgodnie z konwencją kończą się wykrzyknikami.

Od: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/ , sekcja Śmieszne nazwy metod

miku
źródło
1
Również metody kończące ?się na nazywane są metodami predykatowymi.
Waseem
1

Uważaj, nie zawsze tak jest. Weźmy na przykład Ruby Array # concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat .

Gdzie możesz się poważnie poparzyć, to coś takiego MyActiveRecordModel.column_names.concat([url]). Późniejsze wywołania związane z MyActiveRecordModel będą próbowały wyszukać kolumnę „url” dla MyActiveRecordModel i throw.

Zamiast tego musisz go sklonować przed wykonaniem konkatacji. Na szczęście mój zestaw testów złapał ten jeden, ale… uwaga!

wintondeshong
źródło