这是我的测试程序:
module Foo
@@bar1 = "1" # static property of the module?
class << self # open static section
@bar2 = "2" # property in static section, should be static property?
def func1 # static function
puts "bar1: #{@@bar1}"
puts "bar2: #{@bar2}"
end
end
end
Foo.func1
产生输出:
$ ruby test.rb
bar1: 1
bar2:
我的问题是,bar1
和bar2
的声明之间有什么区别?
我以为
@@
添加到bar1
makes it a static/class variable(另外,您不能拥有模块的实例,可以吗?)bar2
放入class << self
区块makes it a static/class variable also。 但是,当它们在func1
打印出来时,bar2
未初始化。他们为什么表现不同?
答案 0 :(得分:3)
首先,让我们暂时忘掉单身人士课程(class << self
)。
模块/类变量(静态变量)与模块/类实例变量不同,如
模块/类变量可以从模块/类及其实例访问,但模块/类实例变量不是。
class X
@@foo = 'foo' # a class variable
@bar = 'bar' # a class instance variable
def self.foo
@@foo
end
def self.bar
@bar
end
def foo
@@foo
end
def bar
@bar
end
end
X.foo #=> "foo"
X.bar #=> "bar"
X.new.foo #=> "foo"
X.new.bar #=> nil
模块/类变量在继承树中共享,但模块/类实例变量不是。
class Parent
@@foo = 'foo in parent'
@bar = 'bar in parent'
def self.foo
@@foo
end
def self.bar
@bar
end
end
class Child < Parent
@@foo = 'foo in child'
@bar = 'bar in child'
end
Parent.foo #=> "foo in child"
Parent.bar #=> "bar in parent"
因此,建议不要使用模块/类变量。
让我们再谈谈模块/类实例变量的行为。
在Ruby中,模块和类是对象,因此它们可以像普通对象一样拥有自己的实例变量。模块/类中的这些实例变量称为模块/类实例变量。
在Ruby中,实例变量属于 ONLY 到主机对象。没有其他对象可以看到它(至少不使用元编程技巧)。
该类的类和实例是2个不同的对象,因此实例无法访问类实例变量。它的类和子类是2个不同的对象,因此它们不能相互访问类实例变量。
最后,让我们谈谈单身人士课程。
每个对象都有自己的单例类。该单例类只有一个实例 - 对象。
模块和类是对象,因此它们可以有自己的单例类。
class << self
打开self
的单件类,在您的代码中,它是模块Foo
。
请注意,模块/类及其单例类是2个不同的对象,因此它们不共享模块/类实例变量。模块/类不继承单例类,单例类也不继承模块/类,因此它们也不共享模块/类变量。