从重写的new()中调用原始的new()方法?

时间:2013-04-17 20:58:38

标签: ruby

我有一个类initialize方法从远程源获取数据,然后使用它来设置其对象属性。

我期待这个课程被大量使用,可能在一个程序中有数百次。我想通过缓存已经实例化的对象来减少开销网络调用,然后当他们要求再次实例化该对象时,我会返回给用户。

为此,我一直在考虑覆盖这个类的新方法。它将检查缓存的对象是否可用,如果可用,则返回该引用。否则,它将为对象调用常规新方法,该方法将分配内存并像往常一样调用initialize

如果我覆盖了课程中的new()方法,是否可以通过类似new的方式调用原始super()方法?

2 个答案:

答案 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?