Ruby中的类级实例变量



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

@@是一个类变量,相当于类实例中的实例变量(@)。

但是,当在类级别上使用实例变量(@)时,它是什么?如果它将定义放在类实例中,那么为什么不在初始化器中定义它呢?

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

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

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

在您的回答中,您不输出类级实例变量。除了通常的语法(@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

最新更新