From: Dan Zwell Date: 2007-09-04T19:16:49+09:00 Subject: Re: Resource Acquisition & Cleanup larsch@belunktum.dk wrote: > Hello Rubyists, > > I am looking for a style or idiom that I can apply to a resource > management problem. I have a number of resources (objects) that I need > to release if any exception is thrown. While ensure-blocks or block > parameters work well for few resources, they get cumbersome when you > have many resources, or when the number of resources is not known. > > Let's say I have something similar to this: > > resources = [] > n.times { |i| > resources.push( Resource.new(i) } > } > > loop { > # do some processing on the resources > } > > n.times { |i| > resources[i].release > } > > If an exception is thrown in the main processing loop, i still need to > release the resources. If an exception is thrown during construction, > i need to release the resources already succesfully created. If an > exception is thrown while releasing a resource during exception > handling, i still need to release the remaining resources. > > Is there a way to do this, especially when 'n' is unknown? > > Regards, > Lars > > > How about this? It should catch and print exceptions that happen during release, but continue looping through the rest of the array. resources.each do |resource| begin resource.release rescue => err puts err end end If you want to also do this upon exceptions in the main processing loop, I would make it into a method and call it like this: def release(resources) resources.each do |resource| begin resource.release rescue => err p err end end end n.times { |i| resources.push( Resource.new(i) } } begin loop { # do some processing on the resources } rescue => err p err # release resources upon error: release(resources) ensure # release resources if there is no error: release(resources) end Hope this helps, Dan