Ruby中的懒惰评估

我有一个Ruby的情况,可能需要创建一个对象,但不能确定.而且由于对象的创建可能是昂贵的,我不是太急于创建它.我认为这是一个明显的懒惰加载的情况.如何定义只有在有人向其发送消息时才创建的对象?该对象将在块中创建.有没有办法在Ruby中进行简单的懒惰加载/初始化?这些东西是由某些宝石支持的,为各种懒惰初始化对象提供不同的解决方案?感谢您的建议!

解决方法

有两种方法

第一个是让调用者处理懒惰对象的创建.这是最简单的解决方案,它是Ruby代码中非常常见的模式.

class ExpensiveObject
  def initialize
    # Expensive stuff here.
  end
end

class Caller
  def some_method
    my_object.do_something
  end

  def my_object
    # Expensive object is created when my_object is called. Subsequent calls
    # will return the same object.
    @my_object ||= ExpensiveObject.new
  end
end

第二个选择是让对象简单地进行初始化.我们在实际对象周围创建一个委托对象来实现这一点.这种方法有点棘手,不推荐,除非你有现有的调用代码,你不能修改,例如.

class ExpensiveObject        # Delegate
  class RealExpensiveObject  # Actual object
    def initialize
      # Expensive stuff here.
    end

    # More methods...
  end

  def initialize(*args)
    @init_args = args
  end

  def method_missing(method,*args)
    # Delegate to expensive object. __object method will create the expensive
    # object if necessary.
    __object__.send(method,*args)
  end

  def __object__
    @object ||= RealExpensiveObject.new(*@init_args)
  end
end

# This will only create the wrapper object (cheap).
obj = ExpensiveObject.new

# Only when the first message is sent will the internal object be initialised.
obj.do_something

您也可以使用stdlib delegate来构建它.

相关文章

以下代码导致我的问题: class Foo def initialize(n=0) @n = n end attr_accessor :n d...
这是我的spec文件,当为上下文添加测试“而不是可单独更新用户余额”时,我得到以下错误. require 's...
我有一个拦截器:DevelopmentMailInterceptor和一个启动拦截器的inititializer setup_mail.rb. 但我想将...
例如,如果我有YAML文件 en: questions: new: 'New Question' other: recent: ...
我听说在RSpec中避免它,let,let !,指定,之前和主题是最佳做法. 关于让,让!之前,如果不使用这些,我该如...
我在Rails中使用MongoDB和mongo_mapper gem,项目足够大.有什么办法可以将数据从Mongoid迁移到 Postgres...