2010-06-26 3 views
8

Zum Beispiel habe ich immer Methoden als String#split, aber nie String.split, die etwas mehr logisch erscheint. Oder vielleicht sogar String::split, weil Sie #split im Namespace String betrachten könnten. Ich habe sogar die Methode allein gesehen, wenn die Klasse angenommen wird (#split).Was ist die Begründung/Geschichte für die # Konvention, Methoden in Ruby zu identifizieren?

Ich verstehe, dass dies die Art ist, wie Methoden in Ri identifiziert werden. Was kam zuerst?

Ist dies zu unterscheiden, zum Beispiel Methoden von Feldern? Ich habe auch gehört, dass dies hilft, Instanzmethoden von Klassenmethoden zu unterscheiden. Aber wo hat das angefangen?

+0

Ich möchte wissen, warum diese Konvention in Büchern/Tutorials nicht erwähnt/erklärt wird, wenn man die Benennungskonventionen von Ruby diskutiert. Ich fand es verwirrend, Methodennamen mit dem Präfix "#" in verschiedenen Diskussionen zu sehen und nur zu erraten, welche Bedeutung das Präfix hatte. Die Tatsache, dass '#' einen Kommentar in der .rb-Quelle beginnt, macht es doppelt verwirrend. Wie du dir vorstellen kannst, ist es nicht einfach, nach etwas zu suchen, also danke, dass du es irgendwo gefragt hast, ich konnte darüber stolpern. Ich frage mich, ob ich in der Lage sein werde, es wieder zu finden, wenn ich diese Details in 6 Monaten nicht-rubinischer Aktivität vergesse ... –

Antwort

8

Der Unterschied zeigt an, wie Sie auf die Methoden zugreifen.

Klassenmethoden verwenden, um den:: Separator, die Nachricht, um anzuzeigen, kann auf das Klasse/Modulobjekt gesendet werden, während Instanzmethoden den # Separator verwenden, um anzuzeigen, dass die Nachricht an ein Instanzobjekt gesendet werden kann.

Ich werde die Complex Klasse (in Ruby 1.9) auswählen, um den Unterschied zu demonstrieren. Sie haben beide Complex::rect und Complex#rect. Diese Methoden sind unterschiedlich und dienen ganz anderen Zwecken. Complex::rect verwendet ein reelles und ein imaginäres Argument und gibt eine neue Instanz von Complex zurück, während Complex#rect ein Array der reellen und imaginären Komponenten der Instanz zurückgibt.

ruby-1.9.1-p378 > x = Complex.rect(1,5) 
=> (1+5i) 
ruby-1.9.1-p378 > x.rect 
=> [1, 5] 
ruby-1.9.1-p378 > x.rect(2, 4) # what would this even do? 
ArgumentError: wrong number of arguments(2 for 0) 
    from (irb):4:in `rect' 
    from (irb):4 
    from /Users/mr/.rvm/rubies/ruby-1.9.1-p378/bin/irb:17:in `<main>' 

Ich denke, der Grund, dass sie nicht . als Trennzeichen für alles verwenden, ist, dass es nicht eindeutig wäre, ob die Methode zu einer Klasse oder eine Instanz gehört. Jetzt, wo ich daran gewöhnt bin, dass Ruby dies tut, sehe ich es tatsächlich als einen Nachteil der Konventionen anderer Sprachen, um ehrlich zu sein.

Auch dies ist ein wenig von einem völlig anderen Thema aus Feldern da alle Nachrichten, die Sie Nachrichten senden können, sind eigentlich, auch wenn es sieht wie ein öffentlich zugänglicher Bereich. Die am nächsten kommenden Felder sind natürlich Attribute oder Instanzvariablen, denen immer @ vorangestellt ist und die nicht direkt von außerhalb der Instanz zugänglich sind, außer Sie verwenden Vererbung oder Object#instance_variable_get/_set.

Warum speziell gewählt :: und #? :: macht für mich Sinn, weil es Namespaces konventionell trennte, aber # war wahrscheinlich nur ein Symbol, das in keiner anderen Nomenklatur verwendet wurde und eindeutig als Trennzeichen für Instanzmethoden erkannt werden konnte.

+0

Jetzt für Bonuspunkte: warum nicht '' 'zum * Aufrufen * von Klassenmethoden verwenden, während' # 'zum Aufrufen von Instanzmethoden? Dann gibt es keine Zweideutigkeit, sowohl beim Lesen der Dokumente als auch im eigentlichen Code. –

+0

@JUST: Sie können * Complex :: rect (1,5) 'tun. Aber da '#' einen Zeilenkommentar beginnt, glaube ich nicht, dass letzterer in absehbarer Zeit adoptiert wird. –

+1

Ich bin mir dessen bewusst. Der Punkt ist, dass es immer noch verdammt seltsam ist, mit "#" statt "." Zu dokumentieren. ** Besonders ** da Sie mit '::' aufrufen können. Es ist eines dieser unaussprechlichen Geheimnisse von Ruby für mich. Da wir bereits die Präfix-Regeln '@' und '@@' haben, machen Sie das Gleiche für Methoden und forcieren (nicht erlauben, * force *) Klassenmethoden mit '::' und force (nicht erlauben, * force *) Instanzmethoden, die mit '.' aufgerufen werden? –

3

Ich verstehe, dass auf diese Weise Methoden in Ri identifiziert werden. Was kam zuerst?

Ja, das ist, wo es herkam. Wenn Sie # verwenden, verknüpft es automatisch Ihre Methoden, sodass Verweise auf andere Methoden in der Dokumentation mit dem Präfix vorangestellt werden.Siehe here:

Namen von Klassen, Quelldateien, und alle Methodennamen einen Unterstrich enthalten, oder durch ein Rautenzeichen vorangestellt sind von Kommentartext zu ihrer Beschreibung automatisch verlinkt.

Sie können eine Methode auf diese Weise jedoch tatsächlich nicht aufrufen. Aber das sollte nicht überraschen. Schließlich ist <cref ...> eine ungültige Anweisung in C#, obwohl es ein gültiges Dokumentations-Tag ist.

+0

Also wurden die ersten Methoden von Hashes bezeichnet? –

+0

@Justin L .: Es ist, was die Konvention geschaffen hat, ja. –

+0

War dies, weil die Rdoc-Dateien Methodennamen als Anchor-IDs verwendeten, und HTML verwendet #, um den Standort-Hash von der Dokumentkennung zu trennen? –

Verwandte Themen