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.
- Permalink
- Trackback
- Comentários (7)
- Ao som de: Red Hot Chili Peppers – Venice Queen
Textos escritos por
Comentários #
Também prefiro definir os métodos de classe com self ao invés do bloco class << self. Fica bem mais legível.
Esse foi uma das muitas dicas que você nos deu no ultimo encontro do guru-sp, valeu a dica ... estou usando desde então ...
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.
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 ?
Flores, para ser sincero, é muito raro eu criar métodos protegidos. Mas eu provavelmente faria algo como
class << self; protected :method1, :method2; end.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.
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