Ruby中的类级别实例变量

时间:2014-08-29 09:51:51

标签: ruby class instance-variables class-variables

请帮助我理解班级实例变量。

@@是一个类变量,它等同于类实例中的实例变量(@)。

但是在类级别上使用什么是实例变量(@)?如果它为类实例添加了一个定义,为什么不在初始化器中定义它呢?

class MyClass
  cattr_reader :class_variable

  def self.new_instance(cv, cliv, iv)
    @@class_variable = cv
    @class_level_instance_variable = cliv
    self.new(iv)
  end

  def initialize(iv)
    @instance_variable = iv
  end

  def use
    puts "class_var=#{self.class.class_variable.inspect}\ninst_var=#{@instance_variable.inspect}\ncliv=#{@class_level_instance_variable.inspect}"
  end
end

c = []
c << MyClass.new_instance(1,2,3)
c[0].use
c << MyClass.new_instance(4,5,6)
c[1].use
c << MyClass.new_instance(7,8,9)
c[2].use

c[0].use
c[1].use
c[2].use

2 个答案:

答案 0 :(得分:2)

在你的回答中,你不输出类级实例变量。除了通常的语法(@foo)之外,还可以通过方法(instance_variable_get(:@foo))访问实例变量。您可以使用此方法读取其他对象的实例变量,而不仅仅是self

这是您代码的修改版本

require 'active_support/core_ext'

class MyClass
  cattr_reader :class_variable

  def self.new_instance(cv, cliv, iv)
    @@class_variable = cv
    @class_level_instance_variable = cliv
    self.new(iv)
  end

  def initialize(iv)
    @instance_variable = iv
  end

  def use
    puts "class_var=#{self.class.class_variable.inspect}"
    puts "class inst var: #{self.class.instance_variable_get(:@class_level_instance_variable)}"
    puts "inst_var=#{@instance_variable.inspect}"
  end
end

c = []
c << MyClass.new_instance(1,2,3)
c << MyClass.new_instance(4,5,6)
c << MyClass.new_instance(7,8,9)

c[0].use
c[1].use
c[2].use
# >> class_var=7
# >> class inst var: 8
# >> inst_var=3
# >> class_var=7
# >> class inst var: 8
# >> inst_var=6
# >> class_var=7
# >> class inst var: 8
# >> inst_var=9

请参阅,类inst var始终为8(正如类var始终为7)。这是因为在完成所有修改后输出值。由于类级变量是共享的,因此最后一次修改获胜。

c << MyClass.new_instance(7,8,9)

如果您要从初始化程序输出(与第一版代码中一样),您会看到不同的结果。

# >> class_var=1
# >> class inst var: 2
# >> inst_var=3
# >> class_var=4
# >> class inst var: 5
# >> inst_var=6
# >> class_var=7
# >> class inst var: 8
# >> inst_var=9

答案 1 :(得分:1)

希望这个例子能解释@(实例)和@@(类)变量之间的区别。

class Animal
  @@total_count = 0

  def self.total_count
    @@total_count
  end

  def initialize
    @@total_count += 1
  end
end

class Cat < Animal
end

Animal.new
Animal.new
Cat.new

Animal.total_count # => 3
Cat.total_count # => 3

正如您所看到的,@@变量在类及其子代之间共享。如果我真的想要计算类的实例数,我必须使用以下代码。

class Animal
  class << self
    attr_accessor :total_count
  end

  @total_count = 0

  def self.total_count
    @total_count
  end

  def initialize
    self.class.total_count += 1
  end
end

class Cat < Animal
  @total_count = 0
end

Animal.new
Animal.new
Cat.new

Animal.total_count # => 2
Cat.total_count # => 1