Если вы хотите лениво оценивать фрагменты кода, используйте прокси:
class LazyProxy
# blank slate... (use BasicObject in Ruby 1.9)
instance_methods.each do |method|
undef_method(method) unless method =~ /^__/
end
def initialize(&lazy_proxy_block)
@lazy_proxy_block = lazy_proxy_block
end
def method_missing(method, *args, &block)
@lazy_proxy_obj ||= @lazy_proxy_block.call # evaluate the real receiver
@lazy_proxy_obj.send(method, *args, &block) # delegate unknown methods to the real receiver
end
end
Затем вы используете это так:
expensive_object = LazyProxy.new { ExpensiveObject.new }
expensive_object.do_something
Вы можете использовать этот код для произвольной сложной инициализации дорогих вещей:
expensive_object = LazyProxy.new do
expensive_helper = ExpensiveHelper.new
do_really_expensive_stuff_with(expensive_helper)
ExpensiveObject.new(:using => expensive_helper)
end
expensive_object.do_something
Как это работает? Вы создаете экземпляр объекта LazyProxy, который содержит инструкции о том, как построить дорогой объект в Proc. Если затем вы вызываете какой-либо метод для прокси-объекта, он сначала создает экземпляр дорогого объекта, а затем делегирует ему вызов метода.