【问题标题】:Removing constant results in constant still being available删除常量会导致常量仍然可用
【发布时间】:2018-05-19 21:12:59
【问题描述】:

检查Object 常量是否已定义

Module.const_defined?('Object')
#=> true

去掉常量

Object.send(:remove_const, 'Object')
#=> Object

检查,Object 常量已删除

Module.const_defined?('Object')
#=> false

现在,如果删除了Object 常量,以下示例如何返回它? :)

String.superclass
#=> Object
new_object = String.superclass.new
#=> #<Object:0x00007fdc18382858>
new_object.class
#=> Object

【问题讨论】:

  • 您是否尝试过使用比ObjectString 更不特别的东西?
  • @muistooshort tbh 我没有。但我现在不认为它应该与不那么特别的东西有任何区别,因为常数是常数。为什么不同的常数会有不同的表现?
  • 因为ObjectString 不只是任何旧常量,它们是语言本身的特性。你不能说'Object'而不与String类交互(因此Object),你不能说Module而不与Object交互,你不能调用一个方法而不与@交互987654338@ 以各种方式(至少通过MethodSymbol)。如果您没有Object,那么您就没有Ruby。您试图从一个非常特殊的具体案例进行推理,最好从更一般的案例开始。
  • Module#remove_const 的文档指出,“删除给定常量的定义,返回该常量的先前值。如果该常量引用了一个模块,则不会更改该模块的名称并可能导致困惑。”更根本的是,你能想象 Matz 允许用户删除类 Object(或 BassicObject)吗?可以想象,这可以达到什么目的?请注意,附带条件是指所有模块,包括自定义模块。顺便说一句,我认为文档可以改进。

标签: ruby ruby-2.5


【解决方案1】:

现在,如果删除Object 常量,以下示例如何返回它?

他们没有。他们不能。常量不是 Ruby 中的对象,因此,它们不可能返回 ::Object 常量。

但是,它们可以返回一个对象,该对象使用字符串'Object' 响应inspect。一个对象,恰好与现在被移除的 ::Object 常量引用的对象相同。

删除常量会删除常量。而已。特别是,它不会删除常量引用的对象。 IFF 该常量是对该对象的唯一 引用,THEN 该对象现在可以进行垃圾回收了。但这里的情况并非如此:::Object 常量不是对Object 类的唯一引用,因为Object 类的每个子类在其Object 指针中都有对Object 类的引用,并且Object 类的每个实例在其class 指针中都有对Object 类的引用。另外,执行引擎的内部数据结构可能有也可能没有对Object 类的引用。

因此,Object 类几乎永远不会被垃圾收集,并且您将始终对它有一些引用,通过这些引用您可以访问它,例如无论::Object 常量是否仍然存在,''.class.superclass 都会让您访问Object 类。

简而言之:您将常量::Object 与该常量引用的对象混淆了。这是一个常见的初学者错误。但是,在几乎所有编程语言中,事物的名称和事物本身之间的区别基本

【讨论】:

  • inspect 非常有道理,谢谢。附带问题:什么是常量,因为它不是对象?
  • 它是一种语言结构,就像语法、if 表达式、definitions 方法等一样。这不是 Ruby 特有的:在几乎所有编程语言中,变量都不是对象/值当然在所有主流语言中。事实上,在大多数语言中(不仅是编程语言,自然语言也是如此),事物和事物名称之间的区别是基本的
猜你喜欢
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 2010-11-17
  • 1970-01-01
相关资源
最近更新 更多