Являются ли переменные класса Ruby плохими?

Когда я реализовал шаблон типа "экземпляр"/singleton, RubyMine уведомил, что использование переменных класса считается плохой формой.

Единственная информация, с которой я столкнулся, - то, что использование переменных класса может сделать наследство немного коротким. Есть ли другая причина, по которой следующий код может вызвать у меня проблемы?

class Settings
  private_class_method :new
  attr_accessor :prop1
  attr_accessor :prop2

  @@instance = nil

  def Settings.instance_of
    @@instance = new unless @@instance
    @@instance
  end
  def initialize
    @prop2 = "random"
  end
end

Кроме того, есть ли лучший способ, с точки зрения Ruby, достичь той же цели, чтобы обеспечить только один экземпляр?

2 ответа

Проблема с переменными класса в Ruby состоит в том, что когда вы наследуете от класса, новый класс не получает новую копию своей собственной переменной класса, а использует ту же самую, что унаследована от его суперкласса.

Например:

class Car
  @@default_max_speed = 100
  def self.default_max_speed
    @@default_max_speed
  end
end

class SuperCar < Car
  @@default_max_speed = 200 # and all cars in the world become turbo-charged
end

SuperCar.default_max_speed # returns 200, makes sense!
Car.default_max_speed # returns 200, oops!

Рекомендуется использовать переменные экземпляра класса (помните, что классы - это просто объекты класса Class в Ruby). Я настоятельно рекомендую прочитать 14-ю главу Eloquent Ruby Расса Олсена, в которой подробно рассматривается эта тема.

Являются ли переменные класса Ruby плохими? Как и любой субъективный вопрос, это зависит от вашей точки зрения. Существует обширная литература по вопросу о глобальных переменных, класс которых синглтона является по существу формой. Возможность вызывать вещи, содержащие состояние внутри метода, которые невидимы при его вызове, что делает трудным понимание вещей и проблематичным в обслуживании.

Для Ruby-1.9.3 и более поздних версий смотрите документацию для лучшего способа:

http://ruby-doc.org/stdlib-2.2.3/libdoc/singleton/rdoc/Singleton.html

Замена -2.2.3 любой версией Ruby, которую вы используете.

В принципе:

Использование¶ ↑

To use Singleton, include the module in your class.

class Klass
   include Singleton
   # ...
end

Синглтоны плохие? Ну, я постоянно использую ruby ​​с 2004 года, и я могу вспомнить только один случай, когда я даже подумывал об использовании синглтона. И я не могу вспомнить детали, поэтому я делаю вывод, что на самом деле я этого не делал. Потребность в синглтоне часто является признаком того, что проблему, которую вы решаете, необходимо переформулировать в более четкой формулировке.

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