让我们首先重新定义GC::start,以便我们可以看到它何时被调用。
module GC
def self.start(full_mark: true, immediate_sweep: true)
puts "old start, full_mark: #{full_mark}, " +
"immediate_sweep: #{immediate_sweep}"
end
end
这里有两种方法可以得到想要的结果。
1.在GC 的单例类中使用Module#prepend
module X
def start(full_mark: true, immediate_sweep: true)
puts "new start, full_mark: #{full_mark}, " +
"immediate_sweep: #{immediate_sweep}"
method(__method__).super_method.call(full_mark: full_mark,
immediate_sweep: immediate_sweep)
end
end
module GC
class << self
prepend X
end
end
GC.start(full_mark: 'cat')
new start, full_mark: cat, immediate_sweep: true
old start, full_mark: cat, immediate_sweep: true
注意:
GC.singleton_class.ancestors
#=> [X, #<Class:GC>, Module, ...]
在GC 的单例类中使用Module#prepend 类似于GC.extend X,只是它将X 放在GC 的单例类之前GC 的祖先。另请参阅Method#super_method、Object#method、Kernel#__method__ 和 Method#call。
还要注意:
GC.singleton_class.public_send(:prepend, X)
可以用来代替:
module GC
class << self
prepend X
end
end
2。使用别名
module GC
class << self
alias old_start start
end
def self.start(full_mark: true, immediate_sweep: true)
puts "new start, full_mark: #{full_mark}, " +
"immediate_sweep: #{immediate_sweep}"
old_start(full_mark: full_mark, immediate_sweep: immediate_sweep)
end
end
GC.start(full_mark: 'cat')
new start, full_mark: cat, immediate_sweep: true
old start, full_mark: cat, immediate_sweep: true
在Module#prepend 在 Ruby v2.0 中首次亮相之前,通常使用别名。