Verwirrt über 'reply_to' vs 'reply_to?'

79

Ich lerne Rails mit railstutorial.org und bin über etwas verwirrt: In diesem Kapitel fordert der Autor uns auf, einige Tests in der Konsole mit der respond_to?Methode für ein Benutzerobjekt durchzuführen, und es funktioniert einwandfrei. Aber später, wenn wir den Test für das :encrypted_passwordAttribut schreiben, verwendet er respond_to.

Aus Neugier habe ich respond_toin der Konsole versucht , ein Benutzerobjekt zu finden, und es wird eine Fehlermeldung angezeigt, dass die Methode nicht vorhanden ist. Leider wird der Test nicht ausgeführt , wenn ich versuche, den Test mit respond_to?anstelle von zu schreiben respond_to.

Könnte mir jemand den Unterschied erklären und warum läuft der Test nur mit respond_to?

agente_secreto
quelle

Antworten:

171

Ruby behandelt ?und !als tatsächliche Zeichen in einem Methodennamen. respond_tound respond_to?sind anders. ?gibt an, dass dies mit wahr oder falsch beantwortet werden soll ( gemäß Konvention; dies ist keine Voraussetzung). Speziell:

respond_to?ist eine Ruby- Methode zum Erkennen, ob die Klasse eine bestimmte Methode enthält. Zum Beispiel,

@user.respond_to?('eat_food')

würde true zurückgeben, wenn die UserKlasse eine eat_foodMethode hat.

respond_toist eine Rails- Methode zum Antworten auf bestimmte Anforderungstypen. Zum Beispiel:

def index
  @people = Person.find(:all)

  respond_to do |format|
    format.html
    format.xml { render :xml => @people.to_xml }
  end
end

In dem von Ihnen bereitgestellten RailsTutorial-Link sehen Sie jedoch eine RSpec- Methode, shoulddie mit der RSpec- respond_toMethode interagiert . Dies wäre in Ihrer Konsole nur verfügbar, wenn Sie es ausführen rails console test.

Tim Sullivan
quelle
Wenn Sie jedoch das Beispiel im Buch lesen, wird reply_to nicht mit einem Anforderungstyp, sondern mit einem Attribut verwendet. Vielleicht überschreibt Rails die Ruby-Methode, damit sie auch Attribute akzeptiert?
agente_secreto
1
Dies ist eine RSpec-Methode zum Testen: rspec.info/documentation ... sie wäre in der Konsole nur verfügbar, wenn Sie ENV auf "Testen" setzen.
Tim Sullivan
3
Ich finde es wirklich seltsam, dass Ruby-Ersteller beschlossen haben, denselben Anweisungsnamen "reply_to" für zwei verschiedene Dinge zu verwenden: herauszufinden, ob ein Objekt eine Methode hat, ODER auf einen Anforderungstyp zu antworten. Oh ja, gibt es eine? das macht sie anders. Beeindruckend. \ o /
Junior Mayhé
4
Dies waren überhaupt keine Ruby-Schöpfer. Die erste ist eine Ruby-Methode. Die zweite ist eine Rails-Methode in ActionController. Die dritte ist eine RSpec-Bibliotheksmethode. ? und ! in Ruby haben Bedeutung, also der Unterschied zwischen reply_to und reply_to? sind gleich der Differenz zwischen trim und trimr.
Tim Sullivan
2
Damit zukünftige Benutzer nicht verwirrt werden, garantiert das ?am Ende eines Methodennamens in Ruby nicht , dass die Methode einen Booleschen Wert zurückgibt. Das ?ist wie jedes andere Zeichen nur ein Teil des Methodennamens. Dass Fragezeichenmethoden einen Booleschen Wert zurückgeben sollten, ist eine etablierte Konvention, die jedoch nicht allgemein befolgt wird. (Siehe zum Beispiel github.com/rails/rails/pull/5329 und die Aufregung, die verursacht wurde, als eine Fragezeichenmethode keinen Bool zurückgab)
Andrew
4

respond_to?ist eine boolesche Bewertung. Das respond_towird (normalerweise) zur Bestimmung der Anzeigeinformationen verwendet. Weitere Informationen hier . Die respond_to?überprüft, ob ein Verfahren vorhanden ist, und gibt true zurück , wenn es funktioniert und falsch , wenn dies nicht der Fall.

Micharch54
quelle
3

Der Test verwendet praktische Helfer, um benutzerfreundlicher zu sein.

Ruby ist Ruby, also würde die Verwendung des guten Alten respond_to?funktionieren, wenn Sie es so nennen:

 @user.respond_to?(:encrypted_password).should be_true

Es gibt eine andere, respond_todie in Controllern verwendet wird, aber immer noch nichts mit denen zu tun hat, die Sie bereits getroffen haben.

apneadiving
quelle