当class
区域出现在另一个类定义中时,一直在观察一些意外行为:
这样的区域会覆盖那里的全班定义。
但是,相同的代码只会向此类添加新方法,如下面的代码所示。
为什么Ruby设计得像这样,如果它没有超越直觉?
require 'pp'
def pp_methods obj
pp obj.methods - nil.methods
end
#first definition of A
class A
def method1
end
end
#add method3 to A
class A
def method3
end
end
class B
#class A got overridden within class B
class A
def method2
end
end
def initialize
a=A.new
pp_methods a # => [:method2]
end
end
a1=A.new
pp_methods a1 # => [:method1,:method3]
b=B.new
a2=A.new
pp_methods a1 # => [:method1,:method3]
pp_methods a2 # => [:method1,:method3]
答案 0 :(得分:3)
能够“重新打开”课程实际上非常有用。通过具备此功能,我们可以轻松地向现有库添加功能,或修复问题(“monkey-patch”),而无需修改实际的库代码。一个人为的例子:
class String
def foo
"bar!"
end
end
"hello".foo # => "bar!"
至于第二种情况,A
实际上是B::A
,这与A
完全不同,因此不会重新打开您的初始A
。我们可以在这里看到:
class A
end
A # => A
class B
end
B # => B
B::A # warning: toplevel constant A referenced by B::A
# => A
class B
class A
end
end
B::A # => B::A
A.object_id # => 70359576062780
B::A.object_id # => 70359575976320