Re: IO not closed by GC


#1

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.


#2

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.


#3

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

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


#4

2006/4/17, Stephan M. 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