Почему в Ruby следует избегать @@class_variables?

Я знаю, что некоторые говорят, что в Ruby следует избегать переменных класса (например, @@class_var) и использовать вместо этого переменную экземпляра (например, @instance_var) в классовой области:

def MyClass
  @@foo = 'bar' # Should not do this.
  @foo = 'bar'  # Should do this.
end

Почему использование переменных класса, нахмуренных в Ruby?

Ответы

Ответ 1

Переменные класса часто подвергаются клевете из-за их иногда запутывающего поведения в отношении наследования:

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

Это часто более полезно.

Ответ 2

Будьте осторожны; class @@variables и instance @variables - это не одно и то же.

По существу, когда вы объявляете класс переменная в базовом классе, ее общий со всеми подклассами. Изменение значение в подклассе повлияет на базовый класс и все его подклассы вплоть до дерева наследования. Такое поведение часто желательно. Но столь же часто это поведение не является тем, что было предусмотрено программист, и это приводит к ошибкам, особенно если программист не первоначально ожидали, что класс будет подклассы кем-то другим.

От: http://sporkmonger.com/2007/2/19/instance-variables-class-variables-and-inheritance-in-ruby