在此代码块中,
@@y = 1
class MyClass
@@y = 2
end
p @@y # => 2
天真地看来,@@y
似乎位于顶级范围内,并且它与@@y
范围内的MyClass
不同。{1}}。为什么@@y
受到MyClass
类定义的影响? (为什么结果为2
?)
答案 0 :(得分:7)
我们来看看这个例子。 @@x
中的Bar
确实与@@x
中的Foo
分开。
class Foo
@@x = 1
end
class Bar
@@x = 2
end
Foo.class_variable_get(:@@x) # => 1
Bar.class_variable_get(:@@x) # => 2
但如果Bar
是Foo
的孩子,会发生什么?
class Foo
@@x = 1
end
class Bar < Foo
@@x = 2
end
Foo.class_variable_get(:@@x) # => 2
Bar.class_variable_get(:@@x) # => 2
在这种情况下,@@x
在两种情况下都是相同的,它是Foo
中声明的那个。
现在,回到你的例子:
@@y = 1
class MyClass
@@y = 2
end
p @@y
第一行在根范围中声明了类变量。 Root是一个特殊对象main
,其类型为Object
。所以,基本上,你是在Object
类上定义一个类变量。由于所有内容都是Object
,因此MyClass
的定义也会继承@@y
并且能够更改它。
答案 1 :(得分:1)
当你这样做时
@@y = 1
您在Object上定义它。由于MyClass是Object的子类,因此它可以访问它的类变量。
@@y = 1
class MyClass
@@y = 2
end
p @@y
puts MyClass.superclass #=> Object
puts Object.class_variables #=> @@y
答案 2 :(得分:-1)