我想做一些涉及到GC.start
调用的实验。
Ruby在运行此命令时告诉我GC
不是一个类:
class GC
def self.start
puts "hello"
super
end
end
但是运行这个,Ruby告诉我GC.start
没有超类,所以我认为我实际上并没有加入原始类,而是以某种方式接管了该名称:
module GC
def self.start
puts "hello"
super
end
end
GC.start
我如何猴子补丁GC.start
?
让我们重新定义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。使用Module#prepend的单例课程中的GC
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, ...]
在Module#prepend
的单身人士类别中使用GC
类似于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中首次亮相之前是常用的。