类重新定义代码在另一个类中的行为和目的

时间:2011-12-21 04:54:19

标签: ruby language-agnostic

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] 

1 个答案:

答案 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