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.

JavaScript Avançado

O JavaScript é a única linguagem que muitos acreditam saber sem nunca terem parado para realmente aprendê-la. Neste workshop rápido você entenderá de verdade todos os conceitos avançados do JavaScript em 4 horas puramente práticas.

Saiba mais Fechar

Conheça também o HOWTO