如果创建一个类变量通常是危险且不可预测的,为什么我们需要它们呢?
如果解决方案只是将类实例变量与类级别访问器一起使用:
class Foo
@variable = :something
def self.getvariable
@variable
end
def self.setvariable(value)
@variable = value
end
end
那为什么我们需要类变量???
答案 0 :(得分:1)
这有几个原因:
这是句法糖。您始终可以使用@@var
获取类变量(无论您是在类还是实例范围内)。这不适用于类的变量实例。
类变量持久存在于此类实例的单例类中。例如:
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
答案 1 :(得分:1)
类变量有时会被使用,但我同意使用本征类通常更有用:
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
答案 2 :(得分: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.connection
类)时,您将获得User
,并且它不会被继承。
已添加:是的,如果您误用它可能会有危险:
@@a = "A"
class A
def self.a
@@a
end
def a
@@a
end
end
puts A.a #=> A
puts A.new.a #=> A