# Resource Acquisition & Cleanup

**URL:** <https://www.ruby-forum.com/t/resource-acquisition-cleanup/113727>\
**Category:** Ruby\
**Created:** [September 4, 2007, 11:51am UTC](https://www.ruby-forum.com/t/resource-acquisition-cleanup/113727 "2007-09-04T11:51:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [September 4, 2007, 11:51am UTC](https://www.ruby-forum.com/t/resource-acquisition-cleanup/113727/1 "2007-09-04T11:51:31Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [September 4, 2007, 12:18pm UTC](https://www.ruby-forum.com/t/resource-acquisition-cleanup/113727/2 "2007-09-04T12:18:37Z")

</div>

removed\_email\_address@domain.invalid wrote:

> resources = []  
> }  
> 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

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [September 4, 2007, 3:21pm UTC](https://www.ruby-forum.com/t/resource-acquisition-cleanup/113727/3 "2007-09-04T15:21:16Z")

</div>

I used to use an idiom like this:

class Rollback  
attr\_reader :procs

def initialize  
@procs = []  
end

def undo(&b)  
@procs \<\< b  
end

def self.rollback  
rb = self.new  
begin  
yield rb  
rescue Exception  
rb.procs.reverse.each do |p|  
p.call rescue Exception  
end  
raise  
end  
end  
end

Rollback.rollback do |rb|  
rb.undo { puts “1” }  
rb.undo { puts “2” }  
rb.undo { puts “3” }  
raise “FOO”  
end

# =\> 3

# =\> 2

# =\> 1

# =\> RuntimeError: FOO

Looking back I think I could/should have picked a better name, but the  
idea is that after you allocate each resource, call rb.undo to set up a  
rollback procedure if an exception is raised later on.

I think I posted this somewhere to ruby-talk a few years ago, but I  
couldn’t find the post.

Paul

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [September 4, 2007, 12:56pm UTC](https://www.ruby-forum.com/t/resource-acquisition-cleanup/113727/4 "2007-09-04T12:56:43Z")

</div>

2007/9/4, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> resources = []  
> }
> 
> 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?

This is pretty simply and should satisfy your requirements:

def your\_method(n)  
res = []  
begin  
n.times {|i| res \<\< Resource.new(i)}

```
loop do
  # main work
end

```

ensure  
res.each {|r| r.release rescue nil}  
end  
end

Kind regards

robert
