说,我有:
class Test
def initialize(m)
@m = m
end
def test
@m
end
end
如何临时为return#test
的所有实例(现有实例和新实例)创建方法,然后稍后恢复原始方法?Test
113
这听起来很简单,但我找不到实现它的好方法。可能是因为我对Ruby的了解不多。
到目前为止我发现的是:
# saving the original method
Test.send(:alias_method, :old_test, :test)
# redefining the method
Test.send(:define_method, :test) { 113 }
# restore the original method
Test.send(:alias_method, :test, :old_test)
哪个可以完成这项工作,但据我所知,如果存在的话,它也会重新定义现有的#old_test
?..感觉就像是一种黑客行为,而不是正确使用元编程?..
- 是否可以在不使用别名的情况下做这样的事情(但也可以不修改源代码
Test
)? - 如果没有(或者如果有更简单/更好的方法),如果您可以修改源代码,您将如何做到这一点
Test
?
如果您能描述实现同一目标的多种方法,即使是那些困难或不切实际的方法,我将不胜感激。只是想了解一下 Ruby 中元编程的灵活性和局限性:)
非常感谢
PS 我开始这一切的原因:我使用 gemrack-throttle
来限制以 开头的请求/api
,但其他 url 不应该受到影响。我想测试所有这些以确保它有效。为了测试节流,我也必须将中间件添加到测试环境中。ApiController
我已经成功地对其进行了测试(使用 minitest),但是不应限制所有其他测试测试,因为如果我们需要在每个请求后等待 1 秒,它会使测试花费更长的时间。
我决定在 minitest 的sRequestSpecificIntervalThrottle#allowed?
中用猴子补丁来暂时禁用所有这些测试的节流,然后在s 中再次重新启用它(否则测试节流本身的测试将失败)。如果您告诉我您将如何处理此问题,我将不胜感激。{ true }
#setup
#teardown
然而,既然我已经开始深入研究元编程,我也只是好奇如何实现这一点(暂时重新定义一个方法),即使我实际上并不打算使用它。