gpt4 book ai didi

ruby - 如何在 Ruby 中干净地 "reattach"一个分离的方法?

转载 作者:数据小太阳 更新时间:2023-10-29 07:58:46 26 4
gpt4 key购买 nike

假设我有这个类:

class Foo
def destroy_target(target)
Missile.launch(target)
end
end

我想暂时消除Foo的破坏力,例如为了测试目的,所以我这样做:

backup = Foo.instance_method(:destroy_target)

class Foo
def destroy_target(target)
Pillow.launch(target)
end
end

这是我的问题:如何将原始方法“重新附加”到 Foo,就好像它一开始就没有被覆盖一样?

我意识到我可以做到:

class Foo
def destroy_target(target)
backup.bind(self).call(target)
end
end

但显然这不是最优的,因为我现在正在包装原始函数。我希望能够在不增加任何开销的情况下无限次地分离和重新附加该方法。

换个方式问;我如何“正确地”将 DetachedMethod 附加到类,即不定义调用分离方法的新方法。


注意:我对临时更改类功能的替代方法不感兴趣。我特别想知道如何用不同的方法替换一个方法,然后干净地恢复原来的方法。

最佳答案

我测试了你的第一个例子,它似乎工作正常。我找不到任何副作用,但这并不意味着没有。

你有没有考虑refinements

对于一个类

class Missile
def self.launch(t)
puts "MISSILE -> #{t}"
end
end

class Pillow
def self.launch(t)
puts "PILLOW -> #{t}"
end
end

class Foo
def destroy_target(target)
Missile.launch(target)
end
end

module PillowLauncher
refine Foo do
def destroy_target(target)
Pillow.launch(target)
end
end
end

module Test
using PillowLauncher
Foo.new.destroy_target("Tatooine")
#=> PILLOW -> Tatooine
end

Foo.new.destroy_target("Tatooine")
#=> MISSILE -> Tatooine

它可能会带来比您的示例更加标准和易于理解的优势。

对于模块

如果 Foo 是一个 Module,你不能直接调用 refine Foo,你会得到一个 TypeError: wrong argument type模块(预期类)

但是,您可以改进它的 singleton_class :

module Foo
def self.destroy_target(target)
Missile.launch(target)
end
end

module PillowLauncher
refine Foo.singleton_class do
def destroy_target(target)
Pillow.launch(target)
end
end
end

module Test
using PillowLauncher
Foo.destroy_target('Tatooine')
#=> PILLOW -> Tatooine
end

Foo.destroy_target('Tatooine')
#=> MISSILE -> Tatooine

我不确定你的笔记:

I am not interested in alternative ways of temporarily changing the functionality of a class. I specifically want to know how to replace a method with a different method, then restore the original method cleanly.

我建议的代码似乎两者兼而有之。

关于ruby - 如何在 Ruby 中干净地 "reattach"一个分离的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40969530/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com