Onde colocar métodos privados em Ruby?

95

A maioria dos blogs, tutoriais ou livros tem métodos privados na parte inferior de qualquer classe / módulo. Esta é a melhor prática?

Acho mais conveniente ter métodos privados quando necessário. Por exemplo:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

Dessa forma, acho o código mais legível em vez de rolar para cima e para baixo continuamente, o que é muito irritante.

Há algo terrivelmente errado nessa abordagem? Ter métodos privados na base não é apenas uma prática recomendada e algo mais?

ZX12R
fonte
na verdade, o seu jeito também não é ruim. Eu também sigo o mesmo em alguns casos, parece mais convenienteprivate def my_method...end
r3bo0t

Respostas:

131

A melhor prática, no meu ponto de vista, é ir sequencialmente e declarar seus métodos sem manter o ponto de vista privado.

No final, você pode tornar qualquer método privado apenas adicionando: private :xmethod

Exemplo:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Isso justifica sua pergunta?

kiddorails
fonte
19
Não acho que seja uma boa ideia do ponto de vista da legibilidade à medida que a aula fica cada vez mais longa.
Alexander Suraphel
2
Eu realmente acho que você deve classificar os métodos por ordem de importância e por que chama o quê, quando todas as outras coisas parecem iguais. Os métodos privados são detalhes de implementação e devem ser a última coisa que o leitor vê, portanto, pertençam à parte inferior do arquivo. Eu concordo com o comentário acima de que isso não funcionará bem com arquivos maiores. Essa não deve ser a resposta aceita, há conselhos muito melhores nesta página.
Luke Cowell
58

Também existe a opção de anexar privateà definição do método desde Ruby 2.1.

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

Olhando para a definição, você sabe instantaneamente se um método é privado, não importa onde esteja definido no arquivo. É um pouco mais de digitação (se você não preencher automaticamente) e nem todos os seus programas defficarão bem alinhados.

Dennis
fonte
5
Você deve ter adicionado a observação de que isso está disponível no Ruby 2.1, onde os métodos retornam a chave com seus próprios nomes: bugs.ruby-lang.org/issues/3753
konole
Acredito que private também pode ser usado como um bloco, também conhecido como incluir alguns métodos privados em private begin ... end
edx
veja a resposta de @devpuppy aqui para uma observação sobre como fazer isso com métodos de classe.
manroe
Adicionar privateapenas uma vez, antes de ymethod, também funciona. Não há necessidade de adicioná-lo várias vezes.
Iulian Onofrei
@IulianOnofrei Se você tivesse outro método abaixo , zmethodsem private, esse método não seria privado. Então, você precisa repeti-lo (pelo menos com Ruby 2.3).
tsauerwein
52

Como outros já indicaram, a convenção é colocar os métodos privados no final, sob uma classe privada. No entanto, você provavelmente também deve saber que muitos programadores usam um método de recuo duplo (4 espaços em vez de 2) para isso. O motivo é que muitas vezes você não verá "privado" em seu editor de texto e presumirá que eles podem ser públicos. Veja abaixo uma ilustração:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

Este método deve evitar que você tenha que rolar para cima e para baixo e deixará outros programadores mais confortáveis ​​em seu código.

Noah Clark
fonte
4
Isso foi toda a raiva quando deixei este comentário em '12. Não vejo mais isso com muita frequência e caiu em desuso.
Noah Clark
privates também podem ser formatados internamente begin..endlogo após private. Em seguida, o recuo pode ser definido automaticamente pelo editor, pois o código dentro do beginé (no exemplo acima) recuado semanticamente com 4 espaços.
Petrus Repo
Eu sigo a mesma abordagem ... primeiro publice depoisprivate
Rahul Goyal
1
Eu nunca vi isso e trabalho com Ruby desde 2007. Em geral, não o recomendaria.
Marnen Laibow-Koser
15

Acho que os métodos públicos são algum tipo de interface do objeto, e é lógico colocá-los no lugar mais proeminente, ou seja, no topo do arquivo.

Flexóide
fonte
5
Sim, coloque os métodos públicos onde é mais provável que você os encontre, geralmente próximo ao início do arquivo, e as coisas que você provavelmente não deveria estar olhando devem ser enterradas próximo ao final. Como um artigo de jornal é escrito, coloque as coisas mais importantes em primeiro lugar.
tadman
14

Você não precisa colocar publicou privateacima de cada método. Normalmente coloco todos os meus métodos privados no final da minha classe. Além disso, não precisa dizer explicitamente publicque os métodos são públicos por padrão. Por exemplo:

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
fonte
Por favor, leia minha pergunta novamente.
Editei
1
É mais uma convenção do que qualquer coisa. O que você está fazendo é válido e se faz mais sentido para você, você deve continuar com ele. Acho que a convenção é mais legível, mas provavelmente é porque foi assim que fui ensinado a escrevê-la, então estou acostumado a isso.
Kyle Decot
o que realmente significa / significa declarar um método como "público"?
ZX12R
6

Estou vindo de um plano de fundo de java e odeio ter que rolar para ver o tipo de método. Eu acho que é uma loucura que não se possa especificar a visibilidade de um método por método sem feiura. Então acabei colocando um comentário #privateantes de cada método de suck e depois declarando private :....

Akostadinov
fonte
1
e Ruby recente pode simplesmente colocá private def method...-lo de forma mais agradável
akostadinov
5

Não gosto de ter que especificar público ou privado para cada método. Colocar todos os métodos privados na parte inferior me permite ter uma única instância de "privado" por arquivo. Acho que é uma questão de gosto.

David
fonte
5

Um estilo é a métodos de grupo juntos para que você só pode usar privatee protecteduma vez por classe, no máximo. Outro estilo é especificar a visibilidade logo após a definição do método:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

A partir do Ruby 2.1.0 defretorna o nome do método como um símbolo, portanto, um estilo mais simplificado é possível:

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

(Observe que usamos private_class_methodpara métodos de classe - caso contrário, obteríamos, NameError: undefined methodpois privateespera um método de instância. Mesmo ao usá-lo como uma macro, como no exemplo original, só afeta a visibilidade dos métodos de instância.)

Eu gosto mais desse estilo de visibilidade embutido, pois permite que você organize os métodos como desejar. Isso diminui o risco de adicionar um novo método no local errado e, inadvertidamente, torná-lo privado.

Quanto à sintaxe do método de classe, você pode lidar com isso desta forma:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end
devpuppy
fonte
este é o único lugar que vi menção da private_class_methodchamada antes, e a última parte sobre como usar o class << selfbloco para evitar a necessidade de usá-lo é uma boa dica. Até agora, eu não sabia que os métodos da classe "nornal" (declarados com em def self.foo; endvez de class << self; def foo; endnão seriam afetados pelo privateespecificador.
manroe
3

Dennis teve a resposta perfeita, ou seja, ao usar ruby> = 2.1, basta prefixar o def com privado (ou protegido, público)

Mas acredito que agora também é possível usar privado como um bloco como em:

private begin
   def foo
   end
   def bar
   end
end

def zip
end
edx
fonte
0

Geralmente ordeno meus métodos da seguinte maneira:

  1. Construtor
  2. Outros métodos públicos, em ordem alfabética
  3. private, escrito apenas uma vez
  4. Métodos privados, em ordem alfabética

Eu uso os recursos de “ir para a definição” em meu editor para que isso não envolva muita rolagem e, em qualquer caso, se a classe for grande o suficiente para que a rolagem se torne problemática, provavelmente deve ser dividida em várias classes.

Marnen Laibow-Koser
fonte
Devo também mencionar que geralmente coloco métodos de conversão (como to_s) perto do final da seção pública.
Marnen Laibow-Koser