Quando falei sobre classes singleton no Ruby, mostrei como era possível atuar no contexto da classe. Uma coisa muito comum entre os desenvolvedores é definir métodos de classe através da classe singleton.

class Person
  class << self
    def description
      "It defines an user"
    end
  end
end

No exemplo acima estamos definindo uma método de classe Person.description. Infelizmente, quando a quantidade de métodos é muito grande, a legibilidade fica prejudicada; você não consegue saber rapidamente se este método é de classe ou instância.

Na maioria das vezes essa escolha é feita sem um objetivo; a explicação é que é possível salvar alguns caracteres ao não digitar self de novo e de novo.

Particularmente, acho que o código acima fica muito mais legível quando escrito desta forma:

class Person
  def self.description
    "It defines an user"
  end
end

Isso não significa que você não deva usar nunca a classe singleton. Eu uso constantemente. Mas não para definir métodos dessa maneira. Eu gosto, por exemplo, de definir atributos.

class Config
  class << self
    attr_accessor :root_dir
  end
end

Um outro uso é quando preciso modificar alguma classe quando um hook é executado, como em plugins do ActiveRecord.

module MyPlugin
  module ClassMethods; end
  module InstanceMethods; end
 
  def self.extended(base)
    class << base
      include InstanceMethods
      extend ClassMethods
    end
  end
end
 
ActiveRecord::Base.extend(MyPlugin)

O método Module#include é privado. Uma alternativa seria injetar este módulo com o método Object#send. Eu só não faço isso pois terei que estender este objeto com os métodos de classe, então prefiro usar a classe singleton para manter o código mais legível.

Finalizando

Definir muitos métodos com a classe singleton pode ser prático, mas prejudica a legibilidade e você não quer que isto aconteça. Prefira a classe singleton para métodos que não estão disponíveis no contexto da classe como o attr_accessor. Não é porque você pode fazer algo, que você deve fazê-lo mesmo assim.

Comentários #

#1 Prodis a.k.a. Fernando Hamasaki disse:
23 Out 11, 07:55PM

Também prefiro definir os métodos de classe com self ao invés do bloco class << self. Fica bem mais legível.

#2 Carlos Corrêa disse:
23 Out 11, 08:02PM

Esse foi uma das muitas dicas que você nos deu no ultimo encontro do guru-sp, valeu a dica ... estou usando desde então ...

#3 Ricardo Bernardelli disse:
23 Out 11, 08:24PM

Eu gosto das duas sintaxes pra ser sincero.

Quando tenho muitos métodos de clase, eu prefiro ter um bloco class << self. Na minha opinião fica mais fácil a leitura se você vai ler de uma forma estrutural o código. Agora se você vai debugar algum código, talvez não fique muito simples mesmo.

Gosto do self.method quando só tem um deles.. nao é nem economizar alguns caracteres, é gosto mesmo.

#4 Rodrigo Flores disse:
23 Out 11, 08:45PM

E quando o método de classe tiver que ser protected ? Você optaria por uma solução assim:

https://gist.github.com/ce256e10541d6edc4c8c

Ou faria via meta classes ?

#5 Nando Vieira disse:
23 Out 11, 09:45PM

Flores, para ser sincero, é muito raro eu criar métodos protegidos. Mas eu provavelmente faria algo como class << self; protected :method1, :method2; end.

#6 Vinicius Baggio disse:
24 Out 11, 10:20AM

Nando, concordo com você, a sintaxe do self. eh melhor, menos "cryptic", porém, no caso de métodos privados (ou vá la, protected), misturar as 2 acho que fica estranho. Mas é de gosto mesmo.

By the way, métodos estáticos/de classe pode ser, e muitas vezes é, um smell de que a gente não modelou as coisas apropriadamente.

#7 Nando Vieira disse:
24 Out 11, 03:16PM

Mas misturar os dois só é preciso em caso de métodos protegidos. No caso de métodos privados você pode usar o método Module.private_class_method. ;)

Deixe um comentário





Não é aceito código HTML: adicione-o no pastie.org ou paste.milk-it.net e poste apenas o link.

Se este é seu primeiro comentário, ele terá que ser aprovado antes de ser exibido.

jQuery: Dominando o framework

Você quer aprender a usar jQuery de verdade? Então chegou a hora! Neste workshop você verá como funciona este framework de JavaScript, entendendo todos os aspectos que fazem do jQuery uma das melhores ferramentas para desenvolvimento de interfaces.

Saiba mais Fechar

Conheça também o HOWTO