gpt4 book ai didi

ruby - 使用现有名称创建新类

转载 作者:数据小太阳 更新时间:2023-10-29 08:31:37 24 4
gpt4 key购买 nike

我们可以创建一个类,然后创建另一个同名的类。这并不奇怪。

[1] pry(main)> class A; end
=> nil
[2] pry(main)> a = A.new
=> #<A:0x0000000bd8a008>
[3] pry(main)> A = Class.new
(pry):3: warning: already initialized constant A
(pry):1: warning: previous definition of A was here
=> A
[4] pry(main)> new_a = A.new
=> #<A:0x0000000be001e0>
[5] pry(main)> a.class.name == new_a.class.name
=> true
[6] pry(main)> a.class == new_a.class
=> false
[7] pry(main)> a.class == A
=> false
[8] pry(main)> new_a.class == A
=> true

然而,在重新定义常量之后,我们得到了似乎是冲突的东西:常量 Anew_a.class 方法返回新类,而 a. class 返回原始类。这些类是不同的,但它们具有相同的名称。这怎么可能?执行这段代码时到底发生了什么?

最佳答案

A 类; end 做了两件事:

  1. 它创建一个新的类对象
  2. 它将此类对象分配给常量A

删除或重新分配常量只会影响 (2),不会更改类对象 (1)。

Ruby 在将类分配给常量时也会设置类名:

A.name #=> "A"

类名存储在一个特殊的实例变量中(见下文),您在检查类的实例时会看到这个名称:

A.new
#=> #<A:0x007febc1230848>
# ^
# |
# +- this is A.name

类名独立于类分配给的常量:

B = A

B.name #=> "A"
B.new #=> #<A:0x007febc1313e68>

这就是为什么您可以创建多个具有相同名称的类。

类名在内部是如何存储的

Ruby 将类名存储在一个特殊的实例变量 __classpath__ 中。它不能从 Ruby 中访问,但如果你想删除这个限制(我已经为这个例子修补了 Ruby),你可以阅读它:

A.instance_variable_get('__classpath__') #=> "A"

甚至改变它:

a = A.new #=> #<A:0x007fe0cd03ad30>
A.instance_variable_set('__classpath__', 'just a name')
A.name #=> "just a name"
a #=> #<just a name:0x007fe0cd03ad30>

关于ruby - 使用现有名称创建新类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28365717/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com