From: Jan Svitok Date: 2006-10-05T08:59:15+09:00 Subject: Re: Associating data with a function Just two ideas, it's too late to actually think ;-) you can change your 'ignored' vesion to something more acceptable: ... def c1 @c1_tmp1 ||= ExpensiveObject.new @c1_tmp2 ||= ExpensiveObject.new tmp1, tmp2 = @c1_tmp1, @c2.tmp2 ... end I was thinking of some kind of delegation, but it got too messy so I abandoned it. Another possibility is to implement a pool of objects directly into ExpensiveObject or to create a layer above it. i.e. something like (not tested, not thread-safe, etc.): class ExtensiveObjectPool class << self def initialize @idle, @busy = [], [] end def with(how_many) objs = allocate(how_many) yield *objs ensure release(objs) end def allocate(num) ret = [] while num > 0 and not @free.empty? num -= 1 ret << @free.pop @busy << ret.last end while num > 0 num -= 1 ret << ExpensiveObject.new @busy << ret.last end ret end def release(objs) @busy.delete(*objs) @free += objs end end class Foo def c1 ExtensiveObjectPool.with(2) do |tmp1, tmp2| result = tmp1 + tmp2 + c2 end end def c2 ExtensiveObjectPool.with(2) do |tmp1, tmp2| result = tmp1 + tmp2 end end end