Où placer les méthodes privées dans Ruby?

95

La plupart des blogs ou tutoriels ou livres ont des méthodes privées au bas de n'importe quelle classe / module. Est-ce la meilleure pratique?

Je trouve plus pratique d'avoir des méthodes privées au besoin. Par exemple:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

De cette façon, je trouve le code plus lisible au lieu de faire défiler de haut en bas en continu, ce qui est très irritant.

Y a-t-il quelque chose qui ne va pas dans cette approche? Avoir des méthodes privées à la base n'est-il pas seulement une meilleure pratique et autre chose?

ZX12R
la source
en fait votre chemin n'est pas mal non plus. Je suis aussi la même chose dans quelques cas, cela me semble plus pratiqueprivate def my_method...end
r3bo0t

Réponses:

131

La meilleure pratique à mon avis est d'aller de manière séquentielle et de déclarer vos méthodes sans garder un point de vue privé.

À la fin, vous pouvez rendre toute méthode privée en ajoutant simplement: private :xmethod

Exemple:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Cela justifie-t-il votre question?

kiddorails
la source
19
Je ne pense pas que ce soit une excellente idée du point de vue de la lisibilité car la classe s'allonge de plus en plus.
Alexander Suraphel
2
Je pense vraiment que vous devriez trier les méthodes par ordre d'importance et par ce qui appelle quoi quand toutes les autres choses semblent égales. Les méthodes privées sont des détails d'implémentation et devraient être la dernière chose que le lecteur voit donc appartenir plus bas dans le fichier. Je suis d'accord avec le commentaire ci-dessus que cela ne fonctionnera pas bien avec des fichiers plus volumineux. Cela ne devrait pas être la réponse acceptée, il y a tellement de meilleurs conseils sur cette page.
Luke Cowell
58

Il existe également la possibilité d'ajouter un préfixe privateà la définition de méthode depuis Ruby 2.1.

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

En regardant la définition, vous savez instantanément si une méthode est privée, peu importe où dans le fichier elle est définie. C'est un peu plus de frappe (si vous ne la complétez pas automatiquement) et tous vos defs ne seront pas bien alignés.

Dennis
la source
5
Vous devriez avoir ajouté une note, que ceci est disponible dans Ruby 2.1 où les méthodes renvoient la clé avec leur propre nom: bugs.ruby-lang.org/issues/3753
konole
Je crois que private peut également être utilisé comme un bloc, c'est-à-dire en enfermant certaines méthodes privées dans private begin ... end
edx
voir la réponse de @devpuppy ici pour une note sur le fait de faire cela avec les méthodes de classe.
manroe
L'ajout d' privateune seule fois, avant le ymethod, fonctionne également. Il n'est pas nécessaire de l'ajouter plusieurs fois.
Iulian Onofrei
@IulianOnofrei Si vous aviez une autre méthode ci-dessous zmethodsans private, cette méthode ne serait pas privée. Donc, vous devez le répéter (au moins avec Ruby 2.3).
tsauerwein le
52

Comme d'autres l'ont déjà souligné, la convention consiste à placer les méthodes privées en bas, sous une classe privée. Cependant, vous devriez probablement aussi savoir que de nombreux programmeurs utilisent une méthode à double retrait (4 espaces au lieu de 2) pour cela. La raison en est que souvent, vous ne verrez pas «privé» dans votre éditeur de texte et supposez qu'ils pourraient être publics. Voir ci-dessous pour une 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

Cette méthode devrait vous éviter d'avoir à faire défiler vers le haut et le bas et rendra les autres programmeurs plus à l'aise dans votre code.

Noah Clark
la source
4
C'était à la mode quand j'ai laissé ce commentaire en 12. Je ne vois plus cela très souvent et c'est tombé en disgrâce.
Noah Clark
les privés peuvent également être formatés à l'intérieur begin..endjuste après private. Ensuite, l'indentation peut être définie automatiquement par l'éditeur puisque le code à l'intérieur du beginest (dans l'exemple ci-dessus) sémantiquement indenté avec 4 espaces.
Petrus Repo
Je suis la même approche ... d'abord publicet ensuiteprivate
Rahul Goyal
1
Je n'ai jamais vu cela et je travaille avec Ruby depuis 2007. Je ne le recommanderais généralement pas.
Marnen Laibow-Koser
15

Je pense que les méthodes publiques sont une sorte d'interface de l'objet, et il est logique de les placer à l'endroit le plus proéminent, c'est-à-dire en haut du fichier.

Flexoïde
la source
5
Oui, placez les méthodes publiques là où vous êtes le plus susceptible de les trouver, généralement vers le haut du fichier, et les choses que vous ne devriez probablement pas regarder devraient être enterrées vers le bas. Comme un article de journal est écrit, mettez les choses les plus importantes en premier.
tadman
14

Vous n'avez pas besoin de mettre publicou privateau - dessus de chaque méthode. Je mets généralement toutes mes méthodes privées au bas de ma classe. De plus, il n'est pas nécessaire de le dire explicitement publiccar les méthodes sont publiques par défaut. Par exemple:

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
la source
Veuillez relire ma question. Je l'
ai
1
C'est plus une convention qu'autre chose. Ce que vous faites est valide et si cela a plus de sens pour vous, vous devez vous y tenir. Je trouve que la convention est plus lisible, mais c'est probablement parce que c'est comme ça qu'on m'a appris à l'écrire, donc je suis juste habituée.
Kyle Decot
que signifie / fait réellement déclarer une méthode comme "publique"?
ZX12R
6

Je viens de fond java et je déteste avoir à faire défiler pour voir le type de méthode. Je pense que c'est insensé qu'on ne puisse pas spécifier la visibilité des méthodes par méthode sans laideur. J'ai donc fini par mettre un commentaire #privateavant chaque méthode suck et ensuite déclarer private :....

Akostadinov
la source
1
et le rubis récent peut juste mettre private def method...pour l'avoir plus gentil
akostadinov
5

Je n'aime pas avoir à spécifier public ou privé pour chaque méthode. Mettre toutes les méthodes privées en bas me permet d'avoir une seule instance de "privé" par fichier. Je suppose que c'est une question de goût.

David
la source
5

Un style est aux méthodes de regrouper de sorte que vous utilisez uniquement privateet protectedune fois par classe au maximum. Un autre style consiste à spécifier la visibilité juste après la définition de la méthode:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

Depuis Ruby 2.1.0 defrenvoie le nom de la méthode sous forme de symbole, donc un style plus simplifié est possible:

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

(Notez que nous utilisons private_class_methodpour les méthodes de classe - sinon nous obtiendrions NameError: undefined methoddepuisprivate attend une méthode d'instance. Même si vous l'utilisez comme macro comme dans l'exemple d'origine, cela n'affecte que la visibilité des méthodes d'instance.)

J'aime mieux ce style de visibilité en ligne, car il vous permet d'organiser les méthodes comme vous le souhaitez. Cela réduit le risque d'ajouter une nouvelle méthode au mauvais endroit et de la rendre privée par inadvertance.

En ce qui concerne la syntaxe de la méthode de classe, vous pouvez la gérer de cette façon à la place:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end
devpuppy
la source
c'est le seul endroit où j'ai vu la mention de l' private_class_methodappel auparavant, et la dernière partie sur l'utilisation du class << selfbloc pour éviter d'avoir à l'utiliser est un bon conseil. Jusqu'à présent, je ne savais pas que les méthodes de classe "nornal" (déclarées avec def self.foo; endau lieu de class << self; def foo; endne seraient pas affectées par le privatespécificateur.
manroe
3

Dennis avait la réponse parfaite, c'est-à-dire que lorsque vous utilisez ruby> = 2.1, préfixez simplement la définition avec private (ou protected, public)

Mais je pense qu'il est désormais également possible d'utiliser private comme bloc comme dans:

private begin
   def foo
   end
   def bar
   end
end

def zip
end
edx
la source
0

Je commande généralement mes méthodes comme suit:

  1. Constructeur
  2. Autres méthodes publiques, par ordre alphabétique
  3. private, écrit une seule fois
  4. Méthodes privées, par ordre alphabétique

J'utilise les fonctionnalités «aller à la définition» dans mon éditeur pour que cela n'implique pas beaucoup de défilement, et dans tous les cas, si la classe est suffisamment grande pour que le défilement devienne problématique, elle devrait probablement être divisée en plusieurs classes.

Marnen Laibow-Koser
la source
Je dois également mentionner que je mets généralement des méthodes de conversion (telles que to_s) à la fin de la section publique.
Marnen Laibow-Koser le