Dove posizionare i metodi privati ​​in Ruby?


95

La maggior parte dei blog o tutorial o libri hanno metodi privati ​​nella parte inferiore di qualsiasi classe / modulo. È questa la migliore pratica?

Trovo più conveniente disporre di metodi privati ​​come e quando necessario. Per esempio:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

In questo modo trovo il codice più leggibile invece di scorrere su e giù continuamente, il che è molto irritante.

C'è qualcosa di terribilmente sbagliato in questo approccio? Avere metodi privati ​​in fondo non è solo una best practice e qualcos'altro?


in realtà anche la tua strada non è male. Seguo anche lo stesso in alcuni casi, mi sembra più convenienteprivate def my_method...end
r3bo0t

Risposte:


131

La migliore pratica dal mio punto di vista è andare in sequenza e dichiarare i tuoi metodi senza mantenere il punto di vista privato.

Alla fine, puoi rendere privato qualsiasi metodo aggiungendo semplicemente: private :xmethod

Esempio:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Questo giustifica la tua domanda?


19
Non penso che questa sia una grande idea dal punto di vista della leggibilità poiché la classe diventa sempre più lunga.
Alexander Suraphel

2
Penso davvero che dovresti ordinare i metodi in ordine di importanza e in base a ciò che chiama ciò che quando tutte le altre cose sembrano uguali. I metodi privati ​​sono dettagli di implementazione e dovrebbero essere l'ultima cosa che il lettore vede, quindi appartengono alla parte inferiore del file. Sono d'accordo con il commento sopra che non funzionerà bene con file più grandi. Questa non dovrebbe essere la risposta accettata, ci sono consigli molto migliori in questa pagina.
Luke Cowell

58

C'è anche la possibilità di anteporre privatealla definizione del metodo a partire da Ruby 2.1.

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

Guardando la definizione, sai immediatamente se un metodo è privato, indipendentemente da dove è definito nel file. È un po 'più di digitazione (se non completi automaticamente) e non tutti i tuoi messaggi defsaranno ben allineati.


5
Avresti dovuto aggiungere nota che questo è disponibile in Ruby 2.1 dove i metodi restituiscono la chiave con il loro nome: bugs.ruby-lang.org/issues/3753
konole

Credo che privato possa anche essere usato come blocco, ovvero racchiudere alcuni metodi privati ​​in privato inizio ... fine
edx

vedere la risposta di @devpuppy qui per una nota su come eseguire questa operazione con i metodi di classe.
manroe

Anche l'aggiunta di privateuna sola volta, prima di ymethod, funziona. Non è necessario aggiungerlo più volte.
Iulian Onofrei

@IulianOnofrei Se avessi un altro metodo zmethodsenza private, questo metodo non sarebbe privato. Quindi, devi ripeterlo (almeno con Ruby 2.3).
tsauerwein

52

Come altri hanno già sottolineato, la convenzione è di mettere i metodi privati ​​in fondo, sotto una classe privata. Tuttavia, probabilmente dovresti anche sapere che molti programmatori usano un metodo a doppio rientro (4 spazi invece di 2) per questo. Il motivo è che spesso non vedrai "privato" nel tuo editor di testo e presumerai che potrebbero essere pubblici. Vedi sotto per un'illustrazione:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

Questo metodo dovrebbe impedirti di scorrere su e giù e renderà gli altri programmatori più a loro agio nel codice.


4
Questo era di gran moda quando ho lasciato questo commento nel '12. Non lo vedo più molto spesso ed è caduto in disgrazia.
Noah Clark

i privati ​​possono anche essere formattati all'interno begin..endsubito dopo private. Quindi il rientro può essere impostato automaticamente dall'editor poiché il codice all'interno di beginè (nell'esempio sopra) rientrato semanticamente con 4 spazi.
Petrus Repo

Seguo lo stesso approccio ... prima publice poiprivate
Rahul Goyal

1
Non l'ho mai visto e lavoro con Ruby dal 2007. Generalmente non lo consiglio.
Marnen Laibow-Koser

15

Penso che i metodi pubblici siano una sorta di interfaccia dell'oggetto, ed è logico posizionarli nella posizione più prominente, ad esempio all'inizio del file.


5
Sì, metti i metodi pubblici dove è più probabile che tu li trovi, generalmente vicino all'inizio del file, e le cose che probabilmente non dovresti guardare dovrebbero essere sepolte vicino alla parte inferiore. Come viene scritto un articolo di giornale, metti al primo posto le cose più importanti.
tadman

14

Non è necessario inserire publico privatesopra ogni metodo. Di solito metto tutti i miei metodi privati ​​in fondo alla classe. Inoltre, non è necessario dire esplicitamente publicpoiché i metodi sono pubblici per impostazione predefinita. Per esempio:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end

end

Per favore leggi di nuovo la mia domanda. L'ho modificato per essere più specifico
ZX12R

1
È più una convenzione che altro. Quello che stai facendo è valido e se ha più senso per te, dovresti mantenerlo. Trovo che la convenzione sia più leggibile, ma probabilmente è perché è così che mi è stato insegnato a scriverla, quindi ci sono abituato.
Kyle Decot

cosa significa / fare effettivamente dichiarare un metodo come "pubblico"?
ZX12R

6

Vengo dallo sfondo di Java e odio dover scorrere per vedere il tipo di metodo. Penso che sia folle che non si possa specificare la visibilità del metodo per metodo senza bruttezza. Quindi ho finito per inserire un commento #privateprima di ogni metodo di succhiamento e poi dichiarare private :....


1
e il recente ruby ​​può semplicemente metterlo private def method...per averlo più bello
akostadinov

5

Non mi piace dover specificare pubblico o privato per ogni metodo. Mettere tutti i metodi privati ​​in fondo mi permette di avere una singola istanza di "privato" per file. Immagino sia una questione di gusti.


5

Uno stile consiste nel raggruppare i metodi insieme in modo da utilizzare al massimo privatee protecteduna volta per classe. Un altro stile è specificare la visibilità subito dopo la definizione del metodo:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

A partire da Ruby 2.1.0 defrestituisce il nome del metodo come simbolo, quindi è possibile uno stile più semplificato:

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

(Nota che usiamo private_class_methodper i metodi di classe, altrimenti avremmo ottenuto NameError: undefined methodpoiché si privateaspetta un metodo di istanza. Anche quando lo si usa come macro come nell'esempio originale, influisce solo sulla visibilità dei metodi di istanza.)

Mi piace di più questo stile di visibilità in linea, poiché ti consente di organizzare i metodi come desideri. Riduce il rischio di aggiungere un nuovo metodo nel posto sbagliato e di renderlo inavvertitamente privato.

Per quanto riguarda la sintassi del metodo di classe, puoi invece gestirla in questo modo:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end

questo è l'unico posto in cui ho visto menzionare la private_class_methodchiamata prima e l'ultima parte sull'uso del class << selfblocco per evitare di doverlo usare è un buon suggerimento. Fino ad ora, non sapevo che i metodi di classe "nornal" (dichiarati con def self.foo; endinvece di class << self; def foo; endnon sarebbero stati influenzati dallo privatespecificatore.
manroe

3

Dennis aveva la risposta perfetta, ovvero, quando si usa ruby> = 2.1, basta anteporre a def private (o protected, public)

Ma credo che ora sia anche possibile utilizzare privato come blocco come in:

private begin
   def foo
   end
   def bar
   end
end

def zip
end

0

Generalmente ordino i miei metodi come segue:

  1. Costruttore
  2. Altri metodi pubblici, in ordine alfabetico
  3. private, scritto una sola volta
  4. Metodi privati, in ordine alfabetico

Uso le funzionalità "vai alla definizione" nel mio editor in modo che questo non comporti molto scorrimento, e in ogni caso, se la classe è abbastanza grande da rendere problematico lo scorrimento, probabilmente dovrebbe essere suddivisa in più classi.


Dovrei anche menzionare che di solito metto metodi di conversione (come to_s) verso la fine della sezione pubblica.
Marnen Laibow-Koser il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.