# Re: IO not closed by GC

**URL:** <https://www.ruby-forum.com/t/re-io-not-closed-by-gc/58013>\
**Category:** Ruby\
**Created:** [April 17, 2006, 7:12pm UTC](https://www.ruby-forum.com/t/re-io-not-closed-by-gc/58013 "2006-04-17T19:12:49Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gennady\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c57346/32.png) [@Gennady\_B](https://www.ruby-forum.com/u/Gennady_B)\
**Post date:** [April 17, 2006, 7:12pm UTC](https://www.ruby-forum.com/t/re-io-not-closed-by-gc/58013/1 "2006-04-17T19:12:49Z")

</div>

But you do not even know when GC will be run, so in your case it might  
not even have kicked in. On the other hand, IO.popen has a nice block  
form that gurantees that an underlying IO object will be closed  
properly. You can rewrite your code as:

os = IO.popen(‘uname -sr’) { |io| io.readlines.to\_s.strip }

Gennady.

---

<div class="post-metadata">

**Author:** ![Gennady\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c57346/32.png) [@Gennady\_B](https://www.ruby-forum.com/u/Gennady_B)\
**Post date:** [April 17, 2006, 7:40pm UTC](https://www.ruby-forum.com/t/re-io-not-closed-by-gc/58013/2 "2006-04-17T19:40:26Z")

</div>

Gennady B. wrote:

> But you do not even know when GC will be run, so in your case it might

Inserting ‘GC.start; sleep 1’ won’t help…

> not even have kicked in. On the other hand, IO.popen has a nice block  
> form that gurantees that an underlying IO object will be closed  
> properly. You can rewrite your code as:
> 
> os = IO.popen(‘uname -sr’) { |io| io.readlines.to\_s.strip }

That works, but is longer. Shorter code is more readable in general…

Anyway, I think an IO object should be closed when not being needed  
anylonger.

Stephan.

---

<div class="post-metadata">

**Author:** ![Gennady\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c57346/32.png) [@Gennady\_B](https://www.ruby-forum.com/u/Gennady_B)\
**Post date:** [April 17, 2006, 8:20pm UTC](https://www.ruby-forum.com/t/re-io-not-closed-by-gc/58013/3 "2006-04-17T20:20:34Z")

</div>

On Tue, 18 Apr 2006, Stephan M. wrote:

> That works, but is longer. Shorter code is more readable in general…
> 
> Anyway, I think an IO object should be closed when not being needed  
> anylonger.

this doesn’t fit the posix process model. under posix fd’s are managed  
per  
process-group, not per process. consider this simple quine:

harp:~ \> cat a.rb  
open **FILE**

IO.new(3).close if ARGV.delete ‘–close’

fork ? Process.wait : print(IO.new(3).read)

harp:~ \> ruby a.rb  
open **FILE**

IO.new(3).close if ARGV.delete ‘–close’

fork ? Process.wait : print(IO.new(3).read)

harp:~ \> ruby a.rb --close  
a.rb:6:in `initialize’: Bad file descriptor (Errno::EBADF)  
from a.rb:6

read this

[fork](http://www.opengroup.org/onlinepubs/000095399/functions/fork.html)

in particular bullet 4. gc’d io object would be incompatible with the  
posix  
process model.

i suppose one could have

io.dont\_gc

but i seems the best POLS approach (not to gc) is the posix route.

regards.

-a

---

<div class="post-metadata">

**Author:** ![Gennady\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c57346/32.png) [@Gennady\_B](https://www.ruby-forum.com/u/Gennady_B)\
**Post date:** [April 18, 2006, 7:05pm UTC](https://www.ruby-forum.com/t/re-io-not-closed-by-gc/58013/4 "2006-04-18T19:05:29Z")

</div>

2006/4/17, Stephan M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Gennady B. wrote:
> 
> > But you do not even know when GC will be run, so in your case it might
> 
> Inserting ‘GC.start; sleep 1’ won’t help…

AFAIK GC is not guaranteed to start when GC.start is invoked plus it  
might not even be guaranteed that this particular object is collected  
at all. It seems to be a common misconception about GC that instances  
that are not referenced any more are immediately cleaned up and do not  
use resources.

> > not even have kicked in. On the other hand, IO.popen has a nice block  
> > form that gurantees that an underlying IO object will be closed  
> > properly. You can rewrite your code as:
> > 
> > os = IO.popen(‘uname -sr’) { |io| io.readlines.to\_s.strip }
> 
> That works, but is longer. Shorter code is more readable in general…

I don’t find the block form less readable than your piece of code.

> Anyway, I think an IO object should be closed when not being needed  
> anylonger.

The difficult part here is to decide when an object is “not needed any  
longer”. Since Ruby has no destructors and automatic variables the  
block form is the most appropriate way to deal with cleanup. I  
suggest you just get used to it.

Kind regards

robert
