3

如果创建类变量通常很危险且不可预测,为什么我们需要它们?如果解决方案只是将类实例变量与类级别访问器一起使用:

class Foo
  @variable = :something

  def self.getvariable
    @variable
  end

  def self.setvariable(value)
    @variable = value
  end
end

那为什么我们需要类变量???

4

3 回答 3

1

这有几个原因:

  1. 它是语法糖。您始终可以使用@@var. 这不适用于类的实例变量。

  2. 类变量对于此类实例的单例类保持不变。例子:

    class Test
    
      @instance_var = 0
      @@class_var = 0
    
      def self.instance_var
        @instance_var
      end
    
      def self.class_var
        @@class_var
      end
    
    end
    
    Test.instance_var #=> 0
    Test.class_var #=> 0
    Test.new.singleton_class.instance_var #=> nil
    Test.new.singleton_class.class_var #=> 0
    
于 2011-07-14T13:27:25.290 回答
1

类变量有时会用到,但我同意使用 eigenclass 通常更有用:

class Foo
  @bar = 'bar'
  class << self
    attr_accessor :bar
  end
end

puts Foo.bar         # bar
puts Foo.bar = 'baz' # baz

上面的继承是安全的,因为它在 Foo 常量中设置了一个变量,而不是一个类变量。

Foo.new.instance_eval { puts @@bar } # error
于 2011-07-14T13:28:24.107 回答
0

这是一个例子(想想 ActiveRecord):

class Base
  def connect(connection)
    @@connection = connection
  end

  def connection
    @@connection
  end
end

class User < Base
end

class SuperUser < User
end

Base.new.connect("A connection")
puts User.new.connection      #=> A connection
puts SuperUser.new.connection #=> A connection

这里的诀窍是类变量可以从实例方法访问并被继承。尝试这个:

class Base
  def self.connect(connection)
    @connection = connection
  end

  def self.connection
    @connection
  end

  def connection
    self.class.connection
  end
end

class User < Base
end

Base.connect("A connection")
puts User.new.connection #=> nil

您将尝试访问它自己的类实例变量(来自nil类),并且它不是继承的。self.connectionUser

补充:是的,如果你滥用它可能会很危险:

@@a = "A"

class A
  def self.a
    @@a
  end
  def a
    @@a
  end
end

puts A.a     #=> A
puts A.new.a #=> A
于 2011-07-14T16:07:55.383 回答