Почему следует избегать @@class_variables в Ruby?
Я знаю, что некоторые говорят, что переменные класса (например, @@class_var
) следует избегать в Ruby и использовать переменную экземпляра (например, @instance_var
) в области видимости вместо:
def MyClass
@@foo = 'bar' # Should not do this.
@foo = 'bar' # Should do this.
end
Почему использование переменных класса не одобряется в Ruby?
2 ответа
Переменные класса часто порочатся из-за их иногда запутанного поведения в отношении наследования:
class Foo
@@foo = 42
def self.foo
@@foo
end
end
class Bar < Foo
@@foo = 23
end
Foo.foo #=> 23
Bar.foo #=> 23
Если вместо этого вы используете переменные экземпляра класса, вы получите:
class Foo
@foo = 42
def self.foo
@foo
end
end
class Bar < Foo
@foo = 23
end
Foo.foo #=> 42
Bar.foo #=> 23
Это часто более полезно.
Быть осторожен; учебный класс @@variables
и экземпляр @variables
это не одно и то же.
По сути, когда вы объявляете переменную класса в базовом классе, она используется всеми подклассами. Изменение его значения в подклассе повлияет на базовый класс и все его подклассы на всем протяжении дерева наследования. Такое поведение часто именно то, что нужно. Но в равной степени часто такое поведение не является тем, что было задумано программистом, и оно приводит к ошибкам, особенно если программист изначально не ожидал, что класс будет переклассифицирован кем-то другим.
От: http://sporkmonger.com/2007/2/19/instance-variables-class-variables-and-inheritance-in-ruby