Bug #1633
closedARGF#close and ARGF#skip are Often Fatal on 1.9
Description
=begin
I don't claim to fully understand this issue, but I'd like to explain some differences between ARGF#close/#skip on 1.8 and 1.9 which seem peculiar.
If ARGV is empty, ARGF refers to STDIN. On all versions ARGF#close suceeds, but ARGF#closed? returns false on 1.9; true on earlier versions.
$ ruby86 -ve 'ARGF.close; p ARGF.closed?'
ruby 1.8.6 (2009-03-31 patchlevel 368) [i686-linux]
true
$ ruby1.8 -ve 'ARGF.close; p ARGF.closed?'
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
true
$ ruby -ve 'ARGF.close; p ARGF.closed?'
ruby 1.9.2dev (2009-06-14 trunk 23689) [i686-linux]
false
Trying to #close an already closed stream raises an IOError, whereas it didn't on 1.8. Thus, you can no longer cavalierly say ARGF.close; you must instead say ARGF.close unless ARGF.closed?, or precede it with a rescue clause.
$ ruby86 -ve 'ARGF.close; ARGF.close' file
ruby 1.8.6 (2009-03-31 patchlevel 368) [i686-linux]
$ ruby1.8 -ve 'ARGF.close; ARGF.close' file
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
$ ruby -ve 'ARGF.close; ARGF.close' file
ruby 1.9.2dev (2009-06-14 trunk 23689) [i686-linux]
-e:1:in `close': closed stream (IOError)
from -e:1:in `close'
from -e:1:in `<main>'
This behaviour impacts ARGF#skip on 1.9, too. Worse, the error message is misleading due to refrencing 'close'; a method that the user did not invoke, thus can't be held responsible for the failure of.
$ ruby86 -ve 'ARGF.read; ARGF.skip' file
ruby 1.8.6 (2009-03-31 patchlevel 368) [i686-linux]
$ ruby1.8 -ve 'ARGF.read; ARGF.skip' file
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
$ ruby -ve 'ARGF.read; ARGF.skip' file
ruby 1.9.2dev (2009-06-14 trunk 23689) [i686-linux]
-e:1:in `close': closed stream (IOError)
from -e:1:in `skip'
from -e:1:in `<main>'
Tangentially, a similarly odd exception is raised on all versions if ARGF#skip is invoked without files to skip to:
$ ruby -ve 'ARGF.skip' file
ruby 1.9.2dev (2009-06-14 trunk 23689) [i686-linux]
-e:1:in `skip': undefined method `close' for nil:NilClass (NoMethodError)
from -e:1:in `<main>'
Given that ARGF is likely to contain a variable number of files, it may be easier if these methods returned nil when there are no more files. This would retain backward compatibility, and reduce error handling logic.
=end
Updated by matz (Yukihiro Matsumoto) almost 16 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r23699.
=end
Updated by matz (Yukihiro Matsumoto) almost 16 years ago
=begin
Hi,
In message "Re: [ruby-core:23853] [Bug #1633] ARGF#close and ARGF#skip are Often Fatal on 1.9"
on Mon, 15 Jun 2009 06:07:37 +0900, Run Paint Run Run redmine@ruby-lang.org writes:
|I don't claim to fully understand this issue, but I'd like to explain some differences between ARGF#close/#skip on 1.8 and 1.9 which seem peculiar.
Both 1.9 and 1.8 have bugs:
-
1.8 ARGF.close does not call #close on T_FILE objects. It calls
rb_io_close() directly, which does not check duplicated close. -
1.9 IO#close does not close file descriptors 0, 1, 2. It should
close them when close is called explicitly. -
ARGF.skip for both versions should not close if current_file is
not initialized.
As a result:
-
"ARGF.close; ARGF.closed?" should be true on 1.9.
-
"ARGF.close; ARGF.close" should raise an exception on 1.8.
-
"ARGF.skip" should not raise any exception on both versions.
-
"ARGF.read; ARGF.skip" should not raise any exceptions.
I will check in the fix.
matz.
=end
Updated by shyouhei (Shyouhei Urabe) over 15 years ago
- Status changed from Closed to Assigned
- Assignee set to wyhaines (Kirk Haines)
=begin
Should also be backported to 1.8.6.
=end
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- Tracker changed from Backport to Bug
- Project changed from 11 to Ruby
- Description updated (diff)
- Status changed from Assigned to Closed
- ruby -v set to ruby 1.9.2dev (2009-06-14 trunk 23689) [i686-linux]
- Backport set to 2.5: UNKNOWN, 2.6: UNKNOWN