Давайте сначала переопределим 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. Используйте Модуль # 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
. См. Также Метод # super_method , Объект # метод , Ядро #__ метод __ и Вызов метода # .
Соблюдайте также что:
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.