我们可以创建一个类,然后创建另一个具有相同名称的类。这并不奇怪。
[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
然而,在重新定义常量后,我们得到似乎是碰撞的东西:常量A
和new_a.class
方法返回新类,而a.class
返回原始类。这些类是不同的,但它们具有相同的名称。这个代码执行时,这怎么可能以及究竟发生了什么?
答案 0 :(得分:3)
class A; end
做了两件事:
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>
答案 1 :(得分:2)
这些类不同,但它们具有相同的名称。这个代码执行时,这怎么可能以及究竟发生了什么?
当您调用某个方法时,两个不同的对象完全可以返回相同的值。对此真的没什么了不起的:
a = [1, 2]
b = 'AB'
a.size # => 2
b.size # => 2
请注意,当我致电a
时,b
和2
都会返回size
,但这并不意味着a
与b
之间存在任何关系。 {{1}}。
答案 2 :(得分:0)
就像在电话簿中有两个“John Smith”条目一样。考虑一下我们有一个班级:
class A
def whoami
puts 'original'
end
end
现在让我们实例化它:
a = new A
a_frozen = new A
a.whoami
#⇒ original
a_frozen.whoami
#⇒ original
让我们修改a
的eighenclass:
class << a
def whoami
'modified'
end
end
a.whoami
#⇒ modified
a_frozen.whoami
#⇒ original
当然,它仍然像:
a.class.name == a_frozen.class.name == 'A'
名称仅限名称,仅此而已。并且不同的类实例共享相同的名称没有问题。
希望它有所帮助。
答案 3 :(得分:0)
a
和new_a
是两个不同类的实例。
您可以使用a.class
和new_a.class
访问这些课程。
这些类是Class
的两个实例。它们似乎具有相同的名称,它们实际上是不同的类,具有不同的方法等。
class A
def a
end
end
a= A.new
A = Class.new
new_a = A.new
puts a.respond_to?(:a) # => true
puts new_a.respond_to?(:a) # => false