Was ist der Zweck von "!" und "?" am Ende der Methodennamen?

Antworten:

160

Es ist "nur Zuckerüberzug" für die Lesbarkeit, aber sie haben gemeinsame Bedeutungen:

  • Methoden, !die mit einer dauerhaften oder potenziell gefährlichen Änderung enden ; beispielsweise:
    • Enumerable#sortGibt eine sortierte Version des Objekts zurück, während Enumerable#sort!es an Ort und Stelle sortiert wird.
    • Gibt in Rails ActiveRecord::Base#savefalse zurück, wenn das Speichern fehlgeschlagen ist, während ActiveRecord::Base#save!eine Ausnahme ausgelöst wird.
    • Kernel::exitbewirkt, dass ein Skript Kernel::exit!sofort beendet wird, wobei alle Exit-Handler umgangen werden.
  • Methoden, die mit ?einem Booleschen Wert enden , lassen den Code noch intuitiver wie ein Satz fließen - if number.zero?lesen sich wie "wenn die Zahl Null ist", sehen aber if number.zeronur seltsam aus.

In Ihrem Beispiel name.reverseauswertet , um eine umgekehrte Zeichenfolge, aber erst nach der name.reverse!Linie funktioniert das nameVariable tatsächlich enthält die Reversed Namen. name.is_binary_data?sieht aus wie "ist nameBinärdaten?".

jtbandes
quelle
22
Ein wichtiger Hinweis ist, dass Sie nur dann eine Bang-Methode haben sollten, wenn Sie auch eine entsprechende Non-Bang-Methode haben. Der Knall wird verwendet, um die "überraschendere" Version der Methode von der "weniger überraschenden" zu unterscheiden. Wenn Sie nur eine Methode haben, ist keine Unterscheidung erforderlich, und Sie sollten sie nicht mit einem Knall benennen. Siehe Array#clearzum Beispiel. Es löscht das Array. Das Löschen des Arrays mutiert es natürlich. Das ist nicht überraschend, der Name macht es schon klar: kein Knall. Siehe ruby-forum.com/topic/176830#773946 .
Jörg W Mittag
2
Hinzufügen zu dem, was @ JörgWMittag laut Ruby Style Guide angegeben hat : Die Namen potenziell gefährlicher Methoden (dh Methoden, die sich selbst oder die Argumente ändern, exit! ( Führt die Finalizer nicht wie exit aus) usw.) sollten mit enden ein Ausrufezeichen, wenn es eine sichere Version dieser gefährlichen Methode gibt .
Tod Birdsall
2
Achtung, das ist nicht immer der Fall. Beispiel: Ruby Array # concat docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat . Wo Sie sich schwer verbrennen können, ist so etwas wie MyActiveRecordModel.column_names.concat (...). Stattdessen müssen Sie es klonen, bevor Sie den Concat ausführen.
Winterondong
8

In Ruby ?bedeutet dies, dass die Methode einen Booleschen !Wert zurückgibt und das Objekt ändert, für das sie aufgerufen wurde. Sie dienen dazu, die Lesbarkeit beim Betrachten des Codes zu verbessern.

J Lundberg
quelle
5

Im Gegensatz zu der - ich nehme an - Mehrheit der Programmiersprachen ...

Ruby, Methoden dürfen mit Fragezeichen oder Ausrufezeichen enden.

Konventionell enden Methoden, die Fragen beantworten (dh Array # leer? Gibt true zurück, wenn der Empfänger leer ist), in Fragezeichen.

Potenziell „gefährliche“ Methoden (dh Methoden, die sich selbst oder die Argumente ändern, beenden! Usw.) enden konventionell mit Ausrufezeichen.

Von: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/ , Abschnitt Lustige Methodennamen

miku
quelle
1
Auch Methoden, die mit enden, ?werden Prädikatmethoden genannt.
Waseem
1

Achtung, das ist nicht immer der Fall. Nehmen Sie zum Beispiel Ruby Array # concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat .

Wo man sich schwer verbrennen kann, ist so etwas wie MyActiveRecordModel.column_names.concat([url]). Spätere Aufrufe im Zusammenhang mit MyActiveRecordModel versuchen, nach einer Spalte mit 'url' für MyActiveRecordModel zu suchen und zu werfen.

Stattdessen müssen Sie es klonen, bevor Sie den Concat ausführen. Zum Glück hat meine Testsuite diese gefangen, aber ... Kopf hoch!

wintondeshong
quelle