Ситуация: у меня есть несколько классов, каждая из которых должна содержать переменную с хэш-конфигурацией; другой хеш для каждого класса, но тот же для всех экземпляров класса.
Сначала я пробовал как это
class A
def self.init config
@@config = config
end
def config
@@config
end
end
class B < A; end
class C < A; end
Но вскоре заметил, что это не сработает, потому что @@config находится в контексте A, а не B или C, таким образом:
B.init "bar"
p B.new.config # => "bar"
p C.new.config # => "bar" - which would be nil if B had it own @@config
C.init "foo"
p B.new.config # => "foo" - which would still be "bar" if C had it own @@config
p C.new.config # => "foo"
Я думал об использовании этого:
modules = [B, C]
modules.each do |m|
m.init(@config[m.name])
end
# ...
B.new # which should then have the correct config
Теперь мне ясно, почему это происходит, но я не уверен, почему это так.
Не может ли он работать и другим способом, удерживая переменную класса в контексте подкласса?
То, что я также обнаружил раздражающим, было фактом, что я всегда является подклассом, даже когда он называется "в" суперклассе. Из этого я сначала ожидал, что код из суперкласса "выполняется в контексте" подкласса.
Некоторое просвещение об этом было бы весьма полезно.
С другой стороны, я, вероятно, должен согласиться, что он работает именно так, и что мне нужно найти другой способ сделать это.
Есть ли способ "мета" для этого? (Я пробовал с class_variable_set и т.д., Но не повезло)
Или, может быть, вся идея в том, что метод "init" ошибочен в первую очередь и есть какой-то другой "шаблон" для этого?
Я мог бы просто сделать @@config хешем, держа все конфиги и всегда выбирать правильный, но я нахожу, что немного неудобно.. (не наследование там решить эту проблему?;)