有没有办法在 Ruby 中改进某个类的初始化方法?

smi*_*art 4 ruby

我正在尝试做这样的事情:

module RefinedHash
  refine Hash do
    def initialize(*args)
      super
      # something here
    end

    def [](key)
      'whatever'
    end
  end
end

class Hello
  using RefinedHash

  def initialize
    h = Hash.new
    p h[:test]
  end
end

Hello.new # => "whatever"
Run Code Online (Sandbox Code Playgroud)

结果[]运行良好并返回'whatever'任何键的调用(仅用于测试目的,以了解我们的改进已被有效应用)。但是,唉,initialize当我在那里实例化我的 Hash 时,任何精炼方法中的代码都不会被执行Hash.new。我是否遗漏了某些东西,或者它是否在某处initialize无法像任何其他方法一样完善?

Max*_*Max 5

我不确定为什么initialize不起作用。可能是因为Class#allocate以某种方式调用它绕过了细化机制?但是您可以优化new,以获得相同的效果:

module RefinedHash
  refine Hash.singleton_class do
    def new(*args)
      obj = super
      # something here
      obj
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

  • `initialize` 是`private`,所以`Class#new` 必须反射调用它(即使用`Object#__send__` / `Object#send`),并且反射(当前)不支持改进。那,还有霍尔格写的。尤其是 YARV 经常以性能的名义破坏 OO 和封装。Rubinius 和 TruffleRuby 做的要少得多,他们不需要,因为他们的优化器要好得多。 (3认同)
  • 哈希、数组、字符串和其他经常使用的对象有点特殊,因为它们在内部进行了大量优化以使用一些快捷方式。这可能包括`Hash.new`不会在新对象上调用`initialize`(甚至不是隐式),而是以更快的方式“手动”构建对象。 (2认同)