Являются ли переменные класса 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 года, и я могу вспомнить только один случай, когда я даже подумывал об использовании синглтона. И я не могу вспомнить детали, поэтому я делаю вывод, что на самом деле я этого не делал. Потребность в синглтоне часто является признаком того, что проблему, которую вы решаете, необходимо переформулировать в более четкой формулировке.