Почему следует избегать @@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

Другие вопросы по тегам