V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
tang3w
V2EX  ›  程序员

关于 Ruby 类变量(class variables)的疑惑

  •  
  •   tang3w ·
    tang3w · 2013-12-16 23:49:29 +08:00 · 3076 次点击
    这是一个创建于 4013 天前的主题,其中的信息可能已经有所发展或是发生改变。
    贴上代码:

    运行结果:
    warning: class variable access from toplevel
    2

    版本是 Ruby 2.0
    我想问的是,为什么输出的是 2 而不是 1
    6 条回复    1970-01-01 08:00:00 +08:00
    toctan
        1
    toctan  
       2013-12-17 00:51:22 +08:00
    由于没有指定 scope, @@a = 2 直接定义在 Object 上, 而 class variable 是由基类和继承类共享的,所以运行结果是 2,看下面

    https://gist.github.com/toctan/7990091

    另外,Ruby 的 class variable 有很多神奇的地方,很多人都建议避免使用,其实,基本上也不会怎么用到:
    http://makandracards.com/makandra/14229-the-many-gotchas-of-ruby-class-variables
    http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/
    ShiningRay
        2
    ShiningRay  
       2013-12-17 02:10:09 +08:00
    所以一般是用类自身的实例变量
    tang3w
        3
    tang3w  
    OP
       2013-12-17 11:08:20 +08:00
    我知道类变量的行为很奇怪,坑也比较多,但是不想逃避这一关,最终还是想弄懂它。

    @toctan 恩,谢谢你的解释。但是仍然让我疑惑的是:为什么 class A 中的 @@a 会被 Object 中的 @@a 覆盖?是不是给 Object 中的 @@a 赋值后,这个类变量就转移到 Object 中了?我知道类变量是在类和子类(继承体系)中共享,但是这个共享的规则也太奇怪了。
    fwee
        4
    fwee  
       2013-12-17 11:58:02 +08:00   ❤️ 1
    @tang3w 是很奇怪啊,所以《ruby编程语言》中建议不要用,还有人提过issue建议删掉这个功能,你既然知道这个规则奇怪就代表你已经弄懂了,就是这么奇怪
    dalang
        5
    dalang  
       2013-12-17 12:35:09 +08:00   ❤️ 1
    @tang3w 正是因为在继承关系中class variable的不符合常理的行为,才导致很多人不建议使用ruby的类变量。
    至少我遇到的情况,在考虑用类变量的时候,类class instance variable总会是更好的选择。
    tang3w
        6
    tang3w  
    OP
       2013-12-17 21:19:11 +08:00
    @fwee
    @dalang

    谢谢你们,通过阅读源码,我搞清楚了 Ruby 2.0 中查找类变量的逻辑。
    总的来说,是逐一遍历祖先链,取最上游的类变量。

    结贴。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3129 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:59 · PVG 12:59 · LAX 20:59 · JFK 23:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.