From: Zachary Scott Date: 2015-01-08T19:03:06-08:00 Subject: [ruby-core:67451] Re: [ruby-trunk - Feature #10718] [Open] IO#close should not raise IOError on closed IO objects. --047d7bfd012a4f439c050c2f65ec Content-Type: text/plain; charset=UTF-8 I think the API is improved but I'm not sure we need to find & replace every occurrence in the stdlib On Thursday, January 8, 2015, wrote: > Issue #10718 has been updated by Eric Wong. > > > Thank you for proposing this. I think this will simplify working with > Ruby IO and make me happier since I work with a lot of IO-related code. > Outside of test cases, I don't forsee compatibility problems either. > > ---------------------------------------- > Feature #10718: IO#close should not raise IOError on closed IO objects. > https://bugs.ruby-lang.org/issues/10718#change-50875 > > * Author: Akira Tanaka > * Status: Open > * Priority: Normal > * Assignee: > * Category: > * Target version: > ---------------------------------------- > I'd like to change IO#close. > It should not raise IOError on closed IO objects. > > We sometimes invoke IO#close only when the IO object is not closed as: > > ``` > f.close if !f.closed? > ``` > > If this issue is accepted, we can write it simply as follows. > > ``` > f.close > ``` > > Simple grep finds many examples. > Following examples are just a little excerpt. > > ``` > lib/webrick/server.rb: sock.close unless sock.closed? > lib/pstore.rb: file.close if !file.closed? > lib/mkmf.rb: @log.close if @log and not @log.closed? > lib/cgi/session.rb: f.close if f and !f.closed? > lib/open-uri.rb: io.close if !io.closed? > lib/net/pop.rb: s.close if s and not s.closed? > lib/net/http.rb: @socket.close if @socket and not @socket.closed? > lib/net/smtp.rb: s.close if s and not s.closed? > lib/shell/process-controller.rb: io.close unless io.closed? > test/ruby/test_io.rb: w.close unless !w || w.closed? > ... > ``` > > I think there is no problem with the behavior which IO#close doesn't raise > an exception on closed IO object. > Because the closed state fulfils the postcondition of the method. > > Moreover raising IOError can smash other exceptions if it is called in > ensure clause. > It makes debugging difficult and the proposed behavior ease it. > > It also useful to close IO object asynchronously. > Asynchronous close can be used for graceful shutdown. > This issue can eliminate "rescue IOError". > See lib/webrick/server.rb and lib/drb/drb.rb for example. > > Note that "double close" is a bad idea in C. > But it is not applicable to Ruby. > A FILE structure is freed on fclose(). > But Ruby's IO object is not freed until GC. > So method invocation on closed object doesn't cause invalid memory access. > A file descriptor (FD) can be reused any time because a signal handler or > another thread may allocate a FD. > But Ruby's IO object is not reused after close. > So it is impossible to close an IO object unintentionally. > > > ---Files-------------------------------- > io-close.patch (1.97 KB) > > > -- > https://bugs.ruby-lang.org/ > --047d7bfd012a4f439c050c2f65ec Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I think the API is improved but I'm not sure we need to find & repl= ace every occurrence in the stdlib

On Thursday, January= 8, 2015, <normalperson@yhbt.n= et> wrote:
Issue #10718 has been u= pdated by Eric Wong.


=C2=A0Thank you for proposing this.=C2=A0 I think this will simplify workin= g with
=C2=A0Ruby IO and make me happier since I work with a lot of IO-related cod= e.
=C2=A0Outside of test cases, I don't forsee compatibility problems eith= er.

----------------------------------------
Feature #10718: IO#close should not raise IOError on closed IO objects.
https://bugs.ruby-lang.org/issues/10718#change-50875

* Author: Akira Tanaka
* Status: Open
* Priority: Normal
* Assignee:
* Category:
* Target version:
----------------------------------------
I'd like to change IO#close.
It should not raise IOError on closed IO objects.

We sometimes invoke IO#close only when the IO object is not closed as:

```
f.close if !f.closed?
```

If this issue is accepted, we can write it simply as follows.

```
f.close
```

Simple grep finds many examples.
Following examples are just a little excerpt.

```
lib/webrick/server.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sock.close unless = sock.closed?
lib/pstore.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file.close if !file.closed= ?
lib/mkmf.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 @log.close if @log and not @= log.closed?
lib/cgi/session.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f.close if f and !f.c= losed?
lib/open-uri.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 io.close if !io.closed?<= br> lib/net/pop.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 s.close if s and not s.closed? lib/net/http.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 @socket.close if @socket= and not @socket.closed?
lib/net/smtp.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 s.close if s and not s.closed?<= br> lib/shell/process-controller.rb:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 io.close unless io.closed?
test/ruby/test_io.rb:=C2=A0 =C2=A0 w.close unless !w || w.closed?
...
```

I think there is no problem with the behavior which IO#close doesn't ra= ise an exception on closed IO object.
Because the closed state fulfils the postcondition of the method.

Moreover raising IOError can smash other exceptions if it is called in ensu= re clause.
It makes debugging difficult and the proposed behavior ease it.

It also useful to close IO object asynchronously.
Asynchronous close can be used for graceful shutdown.
This issue can eliminate "rescue IOError".
See lib/webrick/server.rb and lib/drb/drb.rb for example.

Note that "double close" is a bad idea in C.
But it is not applicable to Ruby.
A FILE structure is freed on fclose().
But Ruby's IO object is not freed until GC.
So method invocation on closed object doesn't cause invalid memory acce= ss.
A file descriptor (FD) can be reused any time because a signal handler or a= nother thread may allocate a FD.
But Ruby's IO object is not reused after close.
So it is impossible to close an IO object unintentionally.


---Files--------------------------------
io-close.patch (1.97 KB)


--
https://bugs.ruby= -lang.org/
--047d7bfd012a4f439c050c2f65ec--