Wo können private Methoden in Ruby platziert werden?

95

Die meisten Blogs, Tutorials oder Bücher verfügen über private Methoden am Ende einer Klasse / eines Moduls. Ist das die beste Vorgehensweise?

Ich finde es bequemer, private Methoden nach Bedarf zu haben. Beispielsweise:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

Auf diese Weise finde ich den Code besser lesbar, anstatt kontinuierlich auf und ab zu scrollen, was sehr irritierend ist.

Stimmt etwas schrecklich an diesem Ansatz nicht? Ist es nicht nur eine bewährte Methode und etwas anderes, private Methoden im Grunde zu haben?

ZX12R
quelle
Eigentlich ist dein Weg auch nicht schlecht. Ich folge auch dem gleichen in einigen Fällen, es fühlt sich bequemer anprivate def my_method...end
r3bo0t

Antworten:

131

Aus meiner Sicht ist es die beste Vorgehensweise, nacheinander vorzugehen und Ihre Methoden zu deklarieren, ohne die Sichtweise privat zu halten.

Am Ende können Sie jede Methode privat machen, indem Sie einfach Folgendes hinzufügen: private :xmethod

Beispiel:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Rechtfertigt dies Ihre Frage?

Kinderschienen
quelle
19
Ich denke nicht, dass dies aus Sicht der Lesbarkeit eine großartige Idee ist, da die Klasse immer länger wird.
Alexander Suraphel
2
Ich denke wirklich, Sie sollten Methoden nach Wichtigkeit sortieren und nach dem, was was nennt, wenn alle anderen Dinge gleich scheinen. Private Methoden sind Implementierungsdetails und sollten das Letzte sein, was der Leser sieht, damit sie tiefer in die Datei gehören. Ich stimme dem obigen Kommentar zu, dass dies bei größeren Dateien nicht gut funktioniert. Dies sollte nicht die akzeptierte Antwort sein, es gibt so viel bessere Ratschläge auf dieser Seite.
Luke Cowell
58

Es gibt auch die Möglichkeit, privateder Methodendefinition seit Ruby 2.1 voranzustellen.

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

Wenn Sie sich die Definition ansehen, wissen Sie sofort, ob eine Methode privat ist, unabhängig davon, wo in der Datei sie definiert ist. Es ist ein bisschen mehr Tippen (wenn Sie nicht automatisch vervollständigen) und nicht alle Ihre defs werden gut ausgerichtet sein.

Dennis
quelle
5
Sie sollten den Hinweis hinzugefügt haben, dass dies in Ruby 2.1 verfügbar ist, wo Methoden Schlüssel mit ihrem eigenen Namen zurückgeben: bugs.ruby-lang.org/issues/3753
konole
Ich glaube, privat kann auch als Block verwendet werden, auch bekannt als das Einschließen einiger privater Methoden in private begin ... end
edx
In der Antwort von @devpuppy finden Sie hier einen Hinweis dazu mit Klassenmethoden.
Manroe
Das Hinzufügen privatenur einmal vor dem ymethodfunktioniert ebenfalls. Es ist nicht erforderlich, es mehrmals hinzuzufügen.
Iulian Onofrei
@IulianOnofrei Wenn Sie eine andere Methode unten zmethodohne hätten private, wäre diese Methode nicht privat. Sie müssen es also wiederholen (zumindest mit Ruby 2.3).
Tsauerwein
52

Wie andere bereits betont haben, besteht die Konvention darin, private Methoden unter eine private Klasse zu stellen. Sie sollten jedoch wahrscheinlich auch wissen, dass viele Programmierer hierfür eine Methode mit doppeltem Einzug (4 Leerzeichen anstelle von 2) verwenden. Der Grund dafür ist, dass Sie in Ihrem Texteditor häufig nicht "privat" sehen und davon ausgehen, dass sie öffentlich sein könnten. Siehe unten für eine Illustration:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

Diese Methode sollte verhindern, dass Sie nach oben und unten scrollen müssen, und andere Programmierer in Ihrem Code komfortabler machen.

Noah Clark
quelle
4
Dies war der letzte Schrei, als ich diesen Kommentar im Jahr '12 hinterließ. Ich sehe das nicht mehr sehr oft und es ist in Ungnade gefallen.
Noah Clark
Gemeinen kann auch innerhalb formatiert werden begin..enddirekt nach private. Dann kann der Einzug vom Editor automatisch gesetzt werden, da der Code innerhalb des begin(im obigen Beispiel) semantisch mit 4 Leerzeichen eingerückt ist.
Petrus Repo
Ich verfolge den gleichen Ansatz ... zuerst publicund dannprivate
Rahul Goyal
1
Ich habe das noch nie gesehen und arbeite seit 2007 mit Ruby. Ich würde es im Allgemeinen nicht empfehlen.
Marnen Laibow-Koser
15

Ich denke, dass öffentliche Methoden eine Art Schnittstelle des Objekts sind, und es ist logisch, sie an der prominentesten Stelle zu platzieren, dh oben in der Datei.

Flexoid
quelle
5
Ja, platzieren Sie die öffentlichen Methoden dort, wo Sie sie am wahrscheinlichsten finden, im Allgemeinen oben in der Datei, und Dinge, die Sie wahrscheinlich nicht betrachten sollten, sollten unten begraben werden. Wie ein Zeitungsartikel geschrieben ist, sollten die wichtigsten Dinge an erster Stelle stehen.
Tadman
14

Sie müssen nicht jede Methode publicoder privatedarüber setzen . Normalerweise setze ich alle meine privaten Methoden am Ende meiner Klasse ein. Sie müssen auch nicht explizit angeben public, dass Methoden standardmäßig öffentlich sind. Beispielsweise:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end

end
Kyle Decot
quelle
Bitte lesen Sie meine Frage noch einmal. Habe es genauer bearbeitet
ZX12R
1
Es ist mehr eine Konvention als alles andere. Was Sie tun, ist gültig und wenn es für Sie sinnvoller ist, sollten Sie dabei bleiben. Ich finde die Konvention besser lesbar, aber das liegt wahrscheinlich daran, dass mir so beigebracht wurde, sie zu schreiben, also bin ich einfach daran gewöhnt.
Kyle Decot
Was bedeutet es eigentlich, eine Methode als "öffentlich" zu deklarieren?
ZX12R
6

Ich komme aus dem Java-Hintergrund und ich hasse es, scrollen zu müssen, um den Methodentyp zu sehen. Ich finde es verrückt, dass man ohne Hässlichkeit keine Sichtbarkeit von Methoden pro Methode festlegen kann. Also habe ich #privatevor jeder Saugmethode einen Kommentar eingefügt und dann erklärt private :....

akostadinov
quelle
1
und neuer Rubin kann es einfach private def method...schöner machen
akostadinov
5

Ich mag es nicht, für jede Methode öffentlich oder privat angeben zu müssen. Wenn ich alle privaten Methoden nach unten setze, kann ich eine einzelne Instanz von "privat" pro Datei haben. Ich denke, es ist Geschmackssache.

David
quelle
5

Ein Stil ist zu Gruppenmethoden zusammen , so dass Sie nur verwenden privateund protectedeinmal pro Klasse höchstens. Ein anderer Stil besteht darin, die Sichtbarkeit direkt nach der Methodendefinition anzugeben:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

Ab Ruby 2.1.0 wird defder Methodenname als Symbol zurückgegeben, sodass ein optimierterer Stil möglich ist:

class Example
  private def my_private_method
  end

  def my_public_method
  end

  protected def my_protected_method
  end

  private_class_method def self.my_private_class_method
  end
end

(Beachten Sie, dass wir private_class_methodfür Klassenmethoden verwenden - sonst würden wir NameError: undefined methodseitdem bekommenprivate erwartet eine Instanzmethode Selbst wenn es als ein Makro wie im ursprünglichen Beispiel unter Verwendung von nur sie die Sichtbarkeit von Instanzmethoden beeinflusst..)

Ich mag diesen Inline-Sichtbarkeitsstil am besten, da Sie damit Methoden nach Ihren Wünschen organisieren können. Es verringert das Risiko, eine neue Methode am falschen Ort hinzuzufügen und sie versehentlich privat zu machen.

Die Syntax der Klassenmethode kann stattdessen folgendermaßen behandelt werden:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end
devpuppy
quelle
Dies ist der einzige Ort, an dem ich den private_class_methodAnruf bereits erwähnt habe, und der letzte Teil über die Verwendung des class << selfBlocks, um zu vermeiden, dass er verwendet werden muss, ist ein guter Tipp. Bis jetzt wusste ich nicht, dass "nornale" Klassenmethoden (deklariert mit def self.foo; endstatt von class << self; def foo; endnicht vom privateSpezifizierer beeinflusst werden würden.
manroe
3

Dennis hatte die perfekte Antwort, dh wenn Sie ruby> = 2.1 verwenden, stellen Sie dem def einfach private (oder geschützte, öffentliche) voran.

Aber ich glaube, dass es jetzt auch möglich ist, privat als Block zu verwenden, wie in:

private begin
   def foo
   end
   def bar
   end
end

def zip
end
edx
quelle
0

Im Allgemeinen bestelle ich meine Methoden wie folgt:

  1. Konstrukteur
  2. Andere öffentliche Methoden in alphabetischer Reihenfolge
  3. private, nur einmal geschrieben
  4. Private Methoden in alphabetischer Reihenfolge

Ich verwende in meinem Editor die Funktionen "Zur Definition gehen", damit nicht viel gescrollt wird. Wenn die Klasse groß genug ist, dass das Scrollen problematisch wird, sollte sie wahrscheinlich in mehrere Klassen unterteilt werden.

Marnen Laibow-Koser
quelle
Ich sollte auch erwähnen, dass ich normalerweise Konvertierungsmethoden (wie to_s) gegen Ende des öffentlichen Abschnitts platziere.
Marnen Laibow-Koser