Ruby Class Singleton常量存储在哪里?

 望天打股 发布于 2023-02-04 15:07

我们假设我们有这个Ruby类:

class MyClass
  class << self
    MC_CONST = 30
  end
end 

然后,让我们实例化MyClass并向对象的元类添加另一个常量:

m = MyClass.new
class << m
  OBJ_MC_CONST = 50
end

对象单例常量没有问题:

m.singleton_class::OBJ_MC_CONST # => 50 <-- [OK]
m.singleton_class.constants.include? :OBJ_MC_CONST # => true <- [OK]

但不完全是我对类单例常量的期望:

MyClass.singleton_class::MC_CONST # => 30 <-- [OK]
MyClass.singleton_class.const_get :MC_CONST # => 30 <-- [OK]
MyClass.singleton_class.constants.include? :MC_CONST # => false <-- [Why???]

为什么在.constants类的元MyClass类上由方法返回的数组不包含:MC_CONST?我在这里错过了什么?

谢谢.


编辑1:毕竟这似乎是MRI 2.x中的一个错误.我已经向Ruby核心团队提出了一个新问题:https://bugs.ruby-lang.org/issues/9413来解决这个问题.

编辑2:这个错误显然已在https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/44628/diff/中修复

1 个回答
  • 我已经对这个问题进行了一些探讨,我认为这是由于MRI的错误/不一致/特异性引起的.

    在MRI 2.1.0上,这段代码:

    class MyClass
      class << self
        MC_CONST = 30
      end
    end 
    
    p MyClass.singleton_class.const_defined? :ABBA_CONST, false
    p MyClass.singleton_class.const_defined? :MC_CONST, false
    p MyClass.singleton_class.constants(false)
    

    产量

    false
    true
    []
    

    所以MC_CONST定义了常量,但是它不能作为类的局部常量(我将错误传递给各种方法以禁用常量分辨率并将其保持在该类的本地),这应该是确实的.如果我们查看Module#常量的文档,它会说:

    返回mod中可访问的常量名称数组.除非将all参数设置为false,否则这包括任何包含的模块中的常量名称(示例在部分的开头).

    另见Module :: const_defined?.

    所以它告诉我们检查const_defined?以更好地理解行为constants,但这两种方法给出了不同的结果!


    此外,在其他Ruby实现上,此代码按预期工作.

    在JRuby 1.7.9上,它产生:

    false
    true
    [:MC_CONST]
    

    在Rubinius 2.2.1上,它产生:

    false
    true
    [:MC_CONST]
    

    这是预期的行为:)

    2023-02-04 15:09 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有