Ruby: Herdar código que funciona com variáveis de classe
A situação: Eu tenho várias classes que devem conter uma variável com um hash de configuração; um hash diferente para cada classe, mas o mesmo para todas as instâncias de uma classe.
No começo, eu tentei assim
class A
def self.init config
@@config = config
end
def config
@@config
end
end
class B < A; end
class C < A; end
Mas logo percebeu que não funcionaria dessa maneira porque @@ config é mantido no contexto de A, não B ou C, portanto:
B.init "bar"
p B.new.config # => "bar"
p C.new.config # => "bar" - which would be nil if B had it's own @@config
C.init "foo"
p B.new.config # => "foo" - which would still be "bar" if C had it's own @@config
p C.new.config # => "foo"
Eu pensei em usá-lo assim:
modules = [B, C]
modules.each do |m|
m.init(@config[m.name])
end
# ...
B.new # which should then have the correct config
Agora, está claro para mim por que isso acontece, mas não tenho certeza sobre o motivo de ser assim.
Não poderia funcionar o contrário também, mantendo a variável de classe no contexto da subclasse?
O que eu também achei irritante foi o fato de que self é sempre a subclasse mesmo quando chamado de 'in' na superclasse. A partir disso, primeiro esperei que o código da superclasse fosse "executado no contexto da" subclasse.
Alguma iluminação sobre isso seria muito apreciada.
Por outro lado, eu provavelmente tenho que aceitar que funciona dessa maneira e que eu tenho que encontrar outra maneira de fazer isso.
Existe uma maneira "meta" de fazer isso? (Eu tentei com class_variable_set etc. mas sem sorte)
Ou talvez a ideia geral do método 'init' tenha sido falha em primeiro lugar e haja algum outro "padrão" para fazer isso?
Eu poderia apenas fazer @@ config um hash, mantendo todas as configurações e sempre escolher o caminho certo, mas acho isso um pouco estranho ... (não há herança para resolver esse tipo de problema?)