Вы когда-нибудь использовали «переменную экземпляра класса» в любом своем коде Ruby? - PullRequest
7 голосов
/ 21 мая 2009

Я могу понять, почему вам понадобится переменная класса для отслеживания таких вещей, как общее количество объектов, которые были созданы в этом классе.

И я могу понять, почему вам понадобится переменная экземпляра для хранения атрибутов определенного объекта в этом классе.

Но переменные экземпляра класса Я просто не могу это оправдать.

Насколько я понимаю, они просто как переменные класса, за исключением того, что они не видны подклассам, как переменные класса .

Кажется, что использование этого было бы весьма ограничено. Или я не прав? Кто-нибудь нашел хорошее применение для переменных экземпляра класса в своем коде? Или вы могли бы привести пример ситуации, когда этот тип нюансов был бы полезен?

Ответы [ 3 ]

4 голосов
/ 21 мая 2009

Скажем, вы хотите посчитать количество экземпляров класса (не включая подклассы)

class A
  @count = 0
  @@count = 0
  def self.inherited(subclass)
    subclass.instance_eval { @count = 0 }
  end
  def self.num_instances
    @count
  end
  def self.num_subclass_instances
    @@count
  end
  def self.new
    @count += 1
    @@count += 1
    super
  end
end
class B < A
end
class C < B
end

A.new
B.new
A.new
B.new
B.new
C.new

A.num_instances #=> 2
A.num_subclass_instances #=> 6
B.num_instances #=> 3
B.num_subclass_instances #=> 6
C.num_instances #=> 1
C.num_subclass_instances #=> 6

Вы не можете использовать переменную класса, так как она используется всеми классы и их подклассы. Обратите внимание, как изменения, внесенные в @@count B и C отражаются в A, но @count не передается.

В целом, это может быть очень полезно для хранения любых специфических для класса настроек. _why использует его в Dwemthy's Array , чтобы указать начальные значения для атрибутов экземпляра, и это часто встречается при выполнении метапрограммирования ruby.

3 голосов
/ 21 мая 2009

Да, на самом деле у меня есть. Это только немного изменено и урезано от того, что у меня было:

class Widget
  # class instance variable pattern
  class << self; attr_accessor :color; end

  def show_color()
    "This widget is #{self.class.color}"
  end
end
class WidgetR < Widget
  @color = "Russet"
end
class WidgetC < Widget
  @color = "Cordovan"
end
class WidgetL < Widget
  @color = "Liver"
end

WidgetR.new.show_color #=> "This widget is Russet"

Но я не уверен, что это действительно необходимо в том случае, если я его использовал. Я мог бы просто переопределить метод. Или при условии цветного метода. Или хранится в переменной класса как Hash. Или даже сохранил копию в каждом случае (хорошо, что это своего рода yech). Я уверен, что есть и другие возможности ...

Существует множество альтернатив, и синтаксис неудобен. Учитывая, что я предполагаю, что случаи, когда это наиболее естественная вещь, вероятно, довольно редки.

Это может помочь вам попытаться воспроизвести это поведение с помощью переменных класса и экземпляра и увидеть, что это трудно достичь (хотя это легко, если вы определяете методы и т. Д.).

C.J.

3 голосов
/ 21 мая 2009

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

http://martinfowler.com/bliki/ClassInstanceVariable.html

...