我有一个类initialize
方法从远程源获取数据,然后使用它来设置其对象属性。
我期待这个课程被大量使用,可能在一个程序中有数百次。我想通过缓存已经实例化的对象来减少开销网络调用,然后当他们要求再次实例化该对象时,我会返回给用户。
为此,我一直在考虑覆盖这个类的新方法。它将检查缓存的对象是否可用,如果可用,则返回该引用。否则,它将为对象调用常规新方法,该方法将分配内存并像往常一样调用initialize
。
如果我覆盖了课程中的new()
方法,是否可以通过类似new
的方式调用原始super()
方法?
答案 0 :(得分:3)
是的,没有参数的super
将使用传递给新方法的相同参数调用父方法。
或者,您可以通过将参数添加到super(p1, p2, ...)
来挑选参数。
通过记住以前的调用,你想要做什么,那就是"memoizing",并且至少有一个memoize gem,或者你可以根据自己的需要编写自己的调用。
使用哈希很容易。使用调用new
方法时使用的参数作为键,值是要返回的实例。如果没有代码示例,很难想出一个自定义的示例,但这是一个简单的,未经测试的版本:
def initialize(*args)
@memoizer ||= {}
return @memoizer[args] if @memoizer[args]
# do what you will with the args in this initializer,
# then create a new instance for the future.
@memoizer[args] = super(args)
end
这个想法是@memoizer
记住调用的“arity”并自动返回类似调用的结果。如果在计算并创建新实例然后返回之前尚未看到该组参数。
当使用相同的输入参数集改变结果时,这会中断。您不希望使用random
或日期/时间值来记忆数据库调用或任何内容,或者返回控件之外的内容。在这些情况下尝试使用它将返回陈旧或错误的值,除非您在方法中设计扫描并定期重新验证@memoizer
值。
此外,没有刷新机制,因此@memoizer
只会增加大小,并且在给定足够不同的输入值的情况下可能会占用所有可用空间。为了解决这个问题,您还可以在将值添加到@memoizer
时设置时间戳,并定期清除超过给定生命周期的条目。那么只有“实时”值会保留在哈希值中。
有用的信息位于:“Memoize Techniques in Ruby and Rails”。
答案 1 :(得分:1)
通过super
或通过alias_method
链
如果你是子类
,那就更好了请检查:When monkey patching a method, can you call the overridden method from the new implementation?