class A
@@path=''
def path
@@path
end
end
class B < A
@@path='b'
end
class C < A
@@path='c'
end
obj= B.new
puts obj.path
按常理来说,应该输出
b
执行 rails s 命令产生的结果是一致的。 但是用 nginx 里却输出的是
c
有大神能帮我解解惑吗,谢谢了。
首先这段代码最后的结果就是 c
,最简单的,开一个 irb 把代码都粘贴上去验证一下就行了。你上面提到的 Nginx 结果没有什么问题,至于 rails s 结果错误,肯定是因为别的原因(我猜想你的 B, C 都是自动加载类,然后实际上验证结果时 C 没有加载或者 B 在 C 之后加载的)。
至于结果为什么是 c
,是因为 Ruby 的类变量会和所有子类以及他们的单例类共享的,即在上述的所有作用域中 @@path
的内存指向都是一样的。
class A
@@path=''
def path_object_id
@@path.object_id
end
def self.path_object_id
@@path.object_id
end
puts path_object_id # => 70139278257540
puts self.new.path_object_id # => 70139278257540
end
class B < A
puts @@path.object_id # => 70139278257540
puts self.new.path_object_id # => 70139278257540
end
class C < A
puts @@path.object_id # => 70139278257540
end
你好,非常感谢你的回答,我按照你的方法验证了一下。我确实是用的自动加载类,可以再请教一下你吗,如果我要达到打印 'b' 的效果的话,有什么办法可以实现吗,类结构不变。
像你这种情况是不想公用属性啊,那应该用实例变量而不是类变量。
但要记得实例变量区分类和他的单例类两个作用域,因此要把初始化的操作移到构造函数中,像上面在类中初始化会得不到你期望的效果
给你补上例子
class A
def initialize
@path=''
end
def path
@path
end
end
class B < A
def initialize
@path='b'
end
end
class C < A
def initialize
@path='c'
end
end
obj= B.new
puts obj.path