665 Stimmen

Warum werden Ausrufezeichen in Ruby-Methoden verwendet?

In Ruby haben einige Methoden ein Fragezeichen ( ? ), die eine Frage stellen wie include? die fragen, ob das betreffende Objekt enthalten ist, und die dann ein true/false zurückgeben.

Aber warum haben manche Methoden Ausrufezeichen ( ! ), was andere nicht tun?

Was bedeutet das?

26 Stimmen

Synonym: Knall, Ausrufezeichen

17 Stimmen

Die akzeptierte Antwort sollte geändert werden in stackoverflow.com/a/612653/109618 . Siehe wobblini.net/bang.txt y ruby-forum.com/topic/176830#773946 -- "Das Knall-Zeichen bedeutet: "Die Knall-Version ist gefährlicher als ihr Gegenstück ohne Knall; mit Vorsicht behandeln"" -Matz

3 Stimmen

Die Bang-Methode wäre eine gute Wahl, wenn nur y alle Knallmethoden waren gefährlich. Leider sind sie das nicht, und so wird es zu einer frustrierenden Übung, sich zu merken, was veränderbar ist und was nicht.

752voto

Todd Gamblin Punkte 56250

Im Allgemeinen enden Methoden, die mit ! zeigen an, dass die Methode das aufgerufene Objekt ändern . Ruby bezeichnet diese als " gefährliche Methoden ", weil sie einen Zustand ändern, auf den sich jemand anderes beziehen könnte. Hier ist ein einfaches Beispiel für Strings:

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

Dies wird ausgegeben:

a string

In den Standardbibliotheken finden sich an vielen Stellen Paare ähnlich benannter Methoden, eine mit dem ! und eine ohne. Die Methoden ohne werden als "sichere Methoden" bezeichnet und geben eine Kopie des Originals mit den Änderungen zurück, die auf die Kopie wobei der Angerufene unverändert bleibt. Hier ist das gleiche Beispiel ohne die ! :

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

Diese Ausgaben:

A STRING
a string

Denken Sie daran, dass dies nur eine Konvention ist, aber viele Ruby-Klassen folgen ihr. Außerdem hilft es Ihnen, den Überblick darüber zu behalten, was in Ihrem Code geändert wird.

3 Stimmen

Es gibt auch Fälle wie Exit versus Exit! und (in Rails) Save versus Save!

33 Stimmen

Seien Sie sehr vorsichtig - viele kleinere Bibliotheken halten sich nicht an diese Konvention. Wenn seltsame Dinge passieren, kann man das Problem oft durch Ersetzen von obj.whatever! durch obj=obj.whatever! beheben. Sehr frustrierend.

129 Stimmen

Bang wird auch für Methoden verwendet, die eine Ausnahme auslösen, wenn die Methode ohne dies nicht tut, z. B.: save y save! en ActiveRecord

183voto

Brian Carper Punkte 68444

Das Ausrufezeichen hat viele Bedeutungen, und manchmal kann man damit nur sagen: "Das ist gefährlich, sei vorsichtig".

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

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

Es handelt sich um eine Namenskonvention, aber viele Menschen verwenden sie auf unterschiedliche Weise. In Ihrem eigenen Code ist es eine gute Daumenregel, ihn immer dann zu verwenden, wenn eine Methode etwas "Gefährliches" tut, insbesondere wenn zwei Methoden mit demselben Namen existieren und eine davon "gefährlicher" ist als die andere. "Gefährlich" kann aber fast alles bedeuten.

94voto

Steven Huwig Punkte 18929

Diese Namenskonvention wurde übernommen von Schema .

1.3.5 Benennungskonventionen

Konventionell sind die Namen der Verfahren die immer einen booleschen Wert zurückgeben normalerweise auf ``?'' enden. Solche Prozeduren werden Prädikate genannt.

Gemäß der Konvention sind die Namen von Prozeduren die Werte an zuvor zugewiesenen Stellen speichern zugewiesenen Speicherplätze (siehe Abschnitt 3.4) normalerweise auf ``!'' enden. Solche Prozeduren werden Mutationsprozeduren genannt. Nach Konvention ist der Wert, der von einer Mutationsprozedur zurückgegebene Wert ist nicht spezifiziert.

5 Stimmen

+1 für diese Antwort, da sie eine Dokumentation hat, die vernünftige Erklärungen für die Verwendung von ! gibt. Wirklich gute Antwort Steven

29voto

Pesto Punkte 23518

! bedeutet normalerweise, dass die Methode auf das Objekt einwirkt, anstatt ein Ergebnis zurückzugeben. Aus dem Buch Ruby programmieren :

Methoden, die "gefährlich" sind oder den Empfänger verändern, können mit einem nachgestellten "!" benannt werden.

28voto

BookOfGreg Punkte 3344

Am ehesten kann man sagen, dass die Methoden mit einem Bang! gefährlich o überraschend Version. Es gibt viele Methoden, die ohne Bang mutieren, wie z.B. .destroy und im Allgemeinen haben Methoden nur dann einen Knall, wenn es in der Kernlib eine sicherere Alternative gibt.

Bei Array haben wir zum Beispiel .compact y .compact! mutieren beide Methoden das Array, aber .compact! gibt nil anstelle von self zurück, wenn es keine nil's im Array gibt, was überraschender ist, als nur self zurückzugeben.

Die einzige nicht-mutierende Methode, die ich mit einem Knall gefunden habe, ist Kernel 's .exit! was überraschender ist als .exit weil man nicht fangen kann SystemExit während der Prozess abgeschlossen wird.

Rails und ActiveRecord setzt diesen Trend fort, indem es Knalleffekte für "überraschende" Effekte wie .create! die bei Fehlern Fehler auslöst.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X