W języku Ruby niektóre metody mają znak zapytania ( ?
), który zadaje takie pytanie include?
, czy pytany obiekt jest uwzględniony, a następnie zwraca wartość prawda / fałsz.
Ale dlaczego niektóre metody mają wykrzykniki ( !
), a inne nie?
Co to znaczy?
Odpowiedzi:
Zasadniczo metody kończące się na
!
wskazują, że metoda zmodyfikuje obiekt, do którego została wywołana . Ruby nazywa je „ niebezpiecznymi metodami ”, ponieważ zmieniają stan, do którego może odwoływać się ktoś inny. Oto prosty przykład dla ciągów:Spowoduje to:
W bibliotekach standardowych jest wiele miejsc, w których zobaczysz pary podobnie nazwanych metod, jedną z tą,
!
a drugą bez. Te bez nazywane są „bezpiecznymi metodami” i zwracają kopię oryginału ze zmianami zastosowanymi do kopii , bez zmiany strony. Oto ten sam przykład bez!
:To daje:
Pamiętaj, że to tylko konwencja, ale przestrzega ją wiele klas Ruby. Pomaga także śledzić zmiany w kodzie.
źródło
save
save!
ActiveRecord
Wykrzyknik oznacza wiele rzeczy, a czasem nie można wiele z tego powiedzieć inaczej niż „to niebezpieczne, bądź ostrożny”.
Jak powiedzieli inni, w standardowych metodach jest często używany do wskazania metody, która powoduje, że obiekt sam się mutuje, ale nie zawsze. Należy pamiętać, że wiele standardowych metod zmienić swój odbiornik i nie mają wykrzyknik (
pop
,shift
,clear
), a niektóre metody z wykrzykników nie zmieniają odbiornik (exit!
). Zobacz na przykład ten artykuł .Inne biblioteki mogą używać go inaczej. W Railsach wykrzyknik często oznacza, że metoda zgłosi wyjątek w przypadku niepowodzenia, a nie po cichu.
Jest to konwencja nazewnictwa, ale wiele osób używa jej w subtelny sposób. W twoim własnym kodzie dobrą zasadą jest używanie go za każdym razem, gdy metoda robi coś „niebezpiecznego”, szczególnie gdy istnieją dwie metody o tej samej nazwie, a jedna z nich jest bardziej „niebezpieczna” niż druga. „Niebezpieczny” może jednak znaczyć prawie wszystko.
źródło
Ta konwencja nazewnictwa została usunięta ze schematu .
źródło
! zazwyczaj oznacza, że metoda działa na obiekt, zamiast zwracać wynik. Z książki Programowanie Ruby :
źródło
Najdokładniej jest powiedzieć, że metody z hukiem! są bardziej niebezpieczną lub zaskakującą wersją. Istnieje wiele metod mutacji bez huku, takich jak
.destroy
i ogólnie metody mają tylko huk, w którym istnieje bezpieczniejsza alternatywa w podstawowej wersji biblioteki.Na przykład w Array mamy
.compact
i.compact!
obie metody mutują tablicę, ale.compact!
zwraca zero zamiast self, jeśli nie ma żadnych zer w tablicy, co jest bardziej zaskakujące niż zwykłe zwracanie self.Jedyna metoda bez mutacji ja z hukiem znaleźć to
Kernel
„s.exit!
, która jest bardziej zaskakujące, niż.exit
dlatego, że nie może złapaćSystemExit
podczas procesu zamykania.Railsy i ActiveRecord kontynuują ten trend, wykorzystując huk dla bardziej „zaskakujących” efektów, takich jak
.create!
wywoływanie błędów po awarii.źródło
Od themomorohoax.com:
Wybuchu można używać w następujący sposób, w zależności od moich osobistych preferencji.
Chodzi o to: używaj huku tylko wtedy, gdy naprawdę zastanawiasz się, czy jest to konieczne, aby zaoszczędzić innym programistom irytujące konieczność sprawdzania, dlaczego używasz huku.
Bang zapewnia dwa sygnały innym programistom.
http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods
źródło
Proste wyjaśnienie:
Ale gdybyś kiedykolwiek nazwał metodę
downcase!
w powyższym wyjaśnieniu,foo
zmieniłby się na stałe na małe.downcase!
nie zwróci nowego obiektu ciągu, ale zastąpi go w miejscu, całkowicie zmieniając nafoo
małe. Radzę nie używać,downcase!
chyba że jest to absolutnie konieczne.źródło
Lubię myśleć o tym jak o wybuchowej zmianie, która niszczy wszystko, co przed nią minęło. Uderzenie lub wykrzyknik oznacza, że dokonujesz trwałej zapisanej zmiany w kodzie.
Jeśli użyjesz na przykład metody Ruby do globalnej substytucji,
gsub!
dokonana przez ciebie podstawa jest trwała.Innym sposobem, w jaki możesz to sobie wyobrazić, jest otwarcie pliku tekstowego, wyszukiwanie i zamiana, a następnie zapisywanie.
!
robi to samo w kodzie.Kolejnym przydatnym przypomnieniem, jeśli pochodzisz ze świata bash, jest
sed -i
podobny efekt wprowadzenia trwale zapisanych zmian.źródło
Nazywane „metodami niszczącymi” Mają tendencję do zmiany oryginalnej kopii obiektu, do którego się odnosisz.
źródło
Konkluzja:
!
metody zmieniają tylko wartość obiektu, do którego są wywoływane, podczas gdy metoda bez!
zwraca wartość zmanipulowaną bez zapisywania obiektu, do którego została wywołana metoda.Używaj tylko
!
wtedy, gdy nie planujesz potrzebować oryginalnej wartości przechowywanej w zmiennej, na której wywołałeś metodę.Wolę robić coś takiego:
LUB
Zamiast
Na wszelki wypadek chciałbym uzyskać dostęp do oryginalnej wartości.
źródło
!
mutuje obiekt zamiast zwracać zmodyfikowaną kopię.User.create!