Classe singleton e definição de métodos de classe
Leia em 1 minuto
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.