为什么并非所有Ruby类都受到我对Object类的修改的影响?

时间:2013-08-14 09:42:17

标签: ruby

class Object
  alias :old_initialize :initialize
  def initialize
    old_initialize
    print "AN OBJECT WAS CREATED"
  end
end

class Test

end

test = Test.new

这可以按预期工作,打印"AN OBJECT WAS CREATED"

但是如果您使用像ArrayHashString这样的核心类,则不会发生任何事情:

array = Array.new
hash = Hash.new
string = String.new

为什么?我原以为它们都是Object的子类,所以对它的任何改变都会有效。但显然它只适用于我的自定义类。

为了让它更加混乱,我意识到正如警告所说,我的修改应该创建一个无限循环,因为"AN OBJECT WAS CREATED"基本上是在创建一个新的String实例 - 但是没有循环发生。现在我更加困惑了。

Ruby 1.8.7

2 个答案:

答案 0 :(得分:5)

如果子类定义了他们自己的initialize并且没有调用父级的initialize,则不会执行prarent的initialize

例如,

class Base
  def initialize; print 'A created' end
end

class Sub1 < Base
  def initialize; super end
end

class Sub2 < Base
  def initialize; end
end

class Sub3 < Base
end

>> Sub1.new
A created=> #<Sub1:0x00000001429630>
>> Sub2.new
=> #<Sub2:0x000000014254e0>
>> Sub3.new
A created=> #<Sub3:0x00000001422128>

答案 1 :(得分:0)

如果ruby像任何其他方法一样考虑initialize,那么当您创建自定义Object时,将遵循方法查找路径并且将采用第一个定义的initialize方法。

class Base
attr_reader :foo

  def initialize
    @foo = 42
  end
end

class A < Base; end

class B < A
  def initialize
    puts "I override initialize"
  end
end

A.new.foo #=> 42
B.new.foo #=> nil

您可以找到有关查找路径解析here

的更多信息