你曾经在任何Ruby代码中使用过“类实例变量”吗?

时间:2009-05-20 23:16:41

标签: ruby class inheritance scope instance-variables

我可以理解为什么你需要一个类变量来跟踪那些已在该类中实例化的对象总数。

我可以理解为什么你需要一个实例变量来存储该类中特定对象的属性。

但是类实例变量我似乎无法证明这一点。

据我所知,它们就像类变量一样,除了它们类变量的子类不可见。

似乎对此的用途非常有限。还是我错了?有没有人在代码中找到了很好的类实例变量?或者你能举例说明这种细微差别有价值的情况吗?

3 个答案:

答案 0 :(得分:4)

假设您要计算类的实例数(不包括子类)

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所做的更改 BC反映在A,但@count未共享。

但是,一般情况下,它对于存储任何特定于类的设置非常有用。 _why在Dwemthy's Array中使用它来指定实例属性的初始值,并且每当执行ruby元编程时它都会出现很多。

答案 1 :(得分:3)

类变量在类的所有实例中共享,包括所有子类。有时,层次结构中的这个变量正是所需要的,但有时您可能更喜欢每个类的不同变量。与类变量不同,类实例变量将为每个类对象采用不同的值。

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

答案 2 :(得分:3)

是的,实际上我有。这只是稍微修改和修剪我所拥有的:

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"

但在我使用它的情况下,我不确定它是否真的有必要。我本可以覆盖这个方法。或者提供了一种颜色方法。或者将它作为哈希存储在类变量中。或者甚至在每个实例中保留一份副本(好吧,那个人有点好)。我确信还有其他可能性......

有各种各样的选择,语法很尴尬。鉴于我猜测它最自然的事情可能相当罕见。

它可能会帮助您尝试使用类和实例变量重现此行为,并看到它很难实现(尽管定义方法等很容易)。

C.J。