it-swarm.com.de

Warum werden in Ruby -Methoden Ausrufezeichen verwendet?

In Ruby haben einige Methoden ein Fragezeichen (?) die eine Frage stellen wie include?, die fragen, ob das betreffende Objekt enthalten ist, gibt dies ein wahr/falsch zurück.

Aber warum haben einige Methoden Ausrufezeichen (!) wo andere nicht?

Was heißt das?

505
Lennie

Im Allgemeinen enden Methoden mit ! gibt an, dass die Methode das aufgerufene Objekt ändern soll. Ruby bezeichnet diese als "gefährliche Methoden", weil sie den Status ändern, auf den eine andere Person möglicherweise verweist. Hier ein einfaches Beispiel für Zeichenfolgen:

foo = "A STRING"  # a string called foo
foo.downcase!     # modifies foo itself
puts foo          # prints modified foo

Dies wird Folgendes ausgeben:

a string

In den Standardbibliotheken gibt es viele Stellen, an denen Sie Paare ähnlich benannter Methoden sehen, eine mit dem ! und eins ohne. Diejenigen ohne werden "sichere Methoden" genannt und geben eine Kopie des Originals mit Änderungen an der Kopie zurück, wobei der Angerufene unverändert bleibt. Hier ist das gleiche Beispiel ohne das !:

foo = "A STRING"    # a string called foo
bar = foo.downcase  # doesn't modify foo; returns a modified string
puts foo            # prints unchanged foo
puts bar            # prints newly created bar

Dies gibt aus:

A STRING
a string

Denken Sie daran, dass dies nur eine Konvention ist, aber viele Ruby) - Klassen folgen ihr. Außerdem können Sie so verfolgen, was in Ihrem Code geändert wird.

579
Todd Gamblin

Das Ausrufezeichen bedeutet viele Dinge, und manchmal kann man nicht viel davon erzählen, außer "das ist gefährlich, sei vorsichtig".

Wie andere gesagt haben, wird es in Standardmethoden oft verwendet, um eine Methode anzugeben, die bewirkt, dass ein Objekt sich selbst mutiert, aber nicht immer. Beachten Sie, dass viele Standardmethoden ihren Empfänger ändern und kein Ausrufezeichen (pop, shift, clear) haben, und einige Methoden mit Ausrufezeichen ihr nicht ändern Empfänger (exit!). Siehe dieser Artikel zum Beispiel.

Andere Bibliotheken verwenden es möglicherweise anders. In Rails bedeutet ein Ausrufezeichen oft, dass die Methode bei einem Fehler eine Ausnahme auslöst, anstatt stillschweigend fehlzuschlagen.

Es ist eine Namenskonvention, die jedoch von vielen Menschen auf subtile Weise unterschiedlich verwendet wird. In Ihrem eigenen Code ist es eine gute Faustregel, ihn immer dann zu verwenden, wenn eine Methode etwas "Gefährliches" tut, insbesondere wenn zwei Methoden mit demselben Namen existieren und eine von ihnen "gefährlicher" ist als die andere. "Gefährlich" kann jedoch fast alles bedeuten.

132
Brian Carper

Diese Namenskonvention wird von Schema aufgehoben.

1.3.5 Namenskonventionen

Konventionell enden die Namen von Prozeduren, die immer einen booleschen Wert zurückgeben, in der Regel mit "?". Solche Prozeduren werden Prädikate genannt.

Üblicherweise enden die Namen von Prozeduren, die Werte an zuvor zugewiesenen Speicherorten speichern (siehe Abschnitt 3.4), mit "!". Solche Verfahren werden Mutationsverfahren genannt. Standardmäßig ist der von einer Mutationsprozedur zurückgegebene Wert nicht angegeben.

71
Steven Huwig

! In der Regel bedeutet dies, dass die Methode auf das Objekt einwirkt, anstatt ein Ergebnis zurückzugeben. Aus dem Buch Programming Ruby :

Methoden, die "gefährlich" sind oder den Empfänger modifizieren, können mit einem abschließenden "!".

24
Pesto

Es ist am genauesten zu sagen, dass Methoden mit einem Bang! sind die mehr gefährlich oder überraschend Version. Es gibt viele Methoden, die ohne einen Knall mutieren, wie .destroy und im Allgemeinen haben Methoden nur Pony, wenn in der Kernbibliothek eine sicherere Alternative existiert.

Zum Beispiel haben wir auf Array .compact und .compact!, beide Methoden mutieren das Array, aber .compact! gibt nil anstelle von self zurück, wenn das Array keine nil enthält. Dies ist überraschender als nur self zurückzugeben.

Die einzige nicht mutierende Methode, die ich bei einem Knall gefunden habe, ist Kernel 's .exit! was überraschender ist als .exit weil Sie SystemExit nicht fangen können, während der Prozess abgeschlossen ist.

Rails und ActiveRecord setzen diesen Trend fort, indem es Bang für überraschendere Effekte wie .create! was Fehler bei einem Fehler auslöst.

18
BookOfGreg

Von themomorohoax.com:

Ein Knall kann auf die folgenden Arten verwendet werden, in der Reihenfolge meiner persönlichen Präferenz.

1) Eine aktive Aufzeichnungsmethode löst einen Fehler aus, wenn die Methode nicht das tut, was sie verspricht.

2) Eine aktive Aufzeichnungsmethode speichert die Aufzeichnung oder eine Methode speichert ein Objekt (z. B. Streifen!).

3) Eine Methode macht etwas "extra", wie Beiträge an einem Ort, oder führt eine Aktion aus.

Der Punkt ist: Verwenden Sie einen Paukenschlag nur, wenn Sie wirklich darüber nachgedacht haben, ob dies erforderlich ist, um anderen Entwicklern den Ärger zu ersparen, zu überprüfen, warum Sie einen Paukenschlag verwenden.

Der Knall bietet zwei Hinweise für andere Entwickler.

1) dass das Objekt nach dem Aufruf der Methode nicht gespeichert werden muss.

2) Wenn Sie die Methode aufrufen, wird die Datenbank geändert.

http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-Rails-methods

16
Edward Castaño

Einfache Erklärung:

foo = "BEST DAY EVER" #assign a string to variable foo.

=> foo.downcase #call method downcase, this is without any exclamation.

"best day ever"  #returns the result in downcase, but no change in value of foo.

=> foo #call the variable foo now.

"BEST DAY EVER" #variable is unchanged.

=> foo.downcase! #call destructive version.

=> foo #call the variable foo now.

"best day ever" #variable has been mutated in place.

Aber wenn Sie jemals eine Methode aufgerufen haben downcase! In der obigen Erläuterung wird foo dauerhaft in den Kleinbuchstaben geändert. downcase! würde kein neues Zeichenfolgenobjekt zurückgeben, sondern die Zeichenfolge ersetzen und dabei foo in Kleinbuchstaben ändern. Ich schlage vor, Sie verwenden nicht downcase! es sei denn, es ist absolut notwendig.

6
Mirage

Als "destruktive Methoden" bezeichnet Sie ändern in der Regel die Originalkopie des Objekts, auf das Sie sich beziehen.

numbers=[1,0,10,5,8]
numbers.collect{|n| puts n*2} # would multiply each number by two
numbers #returns the same original copy
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array
numbers   # returns [nil,nil,nil,nil,nil]
!

Ich stelle mir das gerne als explosive Veränderung vor, die alles zerstört, was davor war. Ein Knall oder ein Ausrufezeichen bedeutet, dass Sie eine dauerhaft gespeicherte Änderung in Ihrem Code vornehmen.

Wenn Sie zum Beispiel Rubys Methode für die globale Substitution verwendengsub!die von Ihnen vorgenommene Ersetzung ist dauerhaft.

Eine andere Möglichkeit, die Sie sich vorstellen können, besteht darin, eine Textdatei zu öffnen, zu suchen und zu ersetzen und anschließend zu speichern. ! macht dasselbe in Ihrem Code.

Eine weitere nützliche Erinnerung, wenn Sie aus der Bash-Welt kommen, ist sed -i hat den ähnlichen Effekt, dauerhaft gespeicherte Änderungen vorzunehmen.

1
Charlie Wood

Endeffekt: ! Methoden ändern nur den Wert des Objekts, auf das sie aufgerufen werden, während eine Methode ohne ! gibt einen manipulierten Wert zurück, ohne das Objekt zu überschreiben, auf das die Methode zugegriffen wurde.

Benutz nur ! Wenn Sie nicht vorhaben, den ursprünglichen Wert zu benötigen, der in der Variablen gespeichert ist, in der Sie die Methode aufgerufen haben.

Ich mache lieber etwas wie:

foo = "Word"
bar = foo.capitalize
puts bar

OR

foo = "Word"
puts foo.capitalize

Anstatt von

foo = "Word"
foo.capitalize!
puts foo

Nur für den Fall, dass ich wieder auf den ursprünglichen Wert zugreifen möchte.

0
Charles