Ruby急切和懒惰的初始化

时间:2015-01-16 18:54:34

标签: ruby lazy-loading eager-loading

我尝试编写这两种方法,以便您可以轻松地在lazyeager之间切换。

例如:

class Foo
  lazy :bar do
    "@bar was initializated lazily"
  end

  eager :bar2 do
    "@bar2 was initializated eagerly"
  end
end

f = Foo.new
puts f.bar
  # @bar was initializated lazily
puts f.bar2
  # @bar2 was initializated eagerly

lazy方法很简单。它会创建一个'' getter'''使用具有该名称的attr_reader方法。并通过块的评估初始化变量。 这只会在您第一次拨打' getter' 时出现。

但是现在我必须编写eager方法,这根本不容易,或者至少对我而言。因为,此方法必须强制initialize eval eager块的指令 AFTER 初始化完成后,我不知道。

我已经尝试在每个initialize块中扩展eager,但是它尚未初始化的对象,因此无法正常工作。你有什么主意吗?现在我正在考虑扩展new方法,以便它调用另一个方法,该方法有一堆块来评估和正确分配。但我认为这有点风险。

1 个答案:

答案 0 :(得分:0)

您可以使用Module#prepend挂钩Foo上的初始化方法。我不知道您的eagerlazy方法的实施情况,或者Foo上如何定义这些方法,但这些方面的某些内容是否可行?

class Foo
  prepend(Module.new do
    def initialize(*args, &block)
      super
      @@_eager_initializers.each do |eager_initializer|
        instance_variable_set(:"@#{eager_initializer.name}", eager_initializer.block.call)
      end
    end
  end)
end