Bug #18767
closedIO.foreach hangs up when passes limit=0
Description
IO.foreach
behaves in an unexpected way in a corner case when passes 0 as a limit parameter. It never stops and hangs up.
IO.foreach('file.txt', 0) { |s| p s }
""
""
""
""
""
""
""
""
""
""
Expected behavior - to raise ArgumentError "invalid limit: 0" like it does the IO.readlines
method.
I observe this behavior on 2.6, 2.7, and 3.0. Didn't check on 3.1 and master though.
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
I've submitted a pull request to fix this: https://github.com/ruby/ruby/pull/5954
Updated by mame (Yusuke Endoh) over 2 years ago
- Status changed from Open to Rejected
I believe this is not a bug. I don't think the current behavior is very useful, but I don't think it is so problematic either. Considering the following example, the behavior is consistent in a sense.
irb(main):001:0> File.write("foo.txt", [*?A..?Z].join)
=> 26
irb(main):002:0> File.foreach("foo.txt", 4).take(4)
=> ["ABCD", "EFGH", "IJKL", "MNOP"]
irb(main):003:0> File.foreach("foo.txt", 3).take(4)
=> ["ABC", "DEF", "GHI", "JKL"]
irb(main):004:0> File.foreach("foo.txt", 2).take(4)
=> ["AB", "CD", "EF", "GH"]
irb(main):005:0> File.foreach("foo.txt", 1).take(4)
=> ["A", "B", "C", "D"]
irb(main):006:0> File.foreach("foo.txt", 0).take(4)
=> ["", "", "", ""]
@andrykonchin (Andrew Konchin) If you really want to change this behavior, please open a feature request with an explanation of a real-world use case.
Updated by andrykonchin (Andrew Konchin) over 2 years ago
I agree that the current behaviour completely makes sense.
The point is that there are other IO methods (that read multiple lines) which don't accept 0 as a limit. So it's more a consistency issue.
For instance IO.readlines
and IO#each_line
:
File.open('Rakefile').each_line(0).to_a
# (irb):8:in `each_line': invalid limit: 0 for each_line (ArgumentError)
IO.readlines('Rakefile', 0)
# (irb):11:in `readlines': invalid limit: 0 for readlines (ArgumentError)
Updated by andrykonchin (Andrew Konchin) over 2 years ago
I still believe that it's a compatibility issue and not a feature request or so. Could the ticket be reopened?
Updated by mame (Yusuke Endoh) over 2 years ago
- Status changed from Rejected to Open
Okay reopened. Sorry, I overlooked the fact that IO#each_line(0)
raises an error.
IMHO, it is reasonable for IO#readlines(0)
to raise an exception. If not, it just gets stuck until the memory is exhausted. I'm unsure about IO#each_line(0)
.
Updated by mame (Yusuke Endoh) over 2 years ago
- Related to Bug #4024: IO#readlines(0) never return added
Updated by andrykonchin (Andrew Konchin) over 2 years ago
Hi, just a kind reminder.
Looks like the issue is accepted but the PR was closed and the fix isn't merged.
Updated by mame (Yusuke Endoh) over 2 years ago
I reopened this issue because there is reasonable doubt about the current situation, but I would like @matz (Yukihiro Matsumoto) 's judgment on whether and how it should actually be fixed.
Updated by matz (Yukihiro Matsumoto) over 2 years ago
OK, let's make it raise exceptions for zero length.
Matz.
Updated by jeremyevans (Jeremy Evans) over 2 years ago
- Status changed from Open to Closed
Applied in changeset git|21cac42385e1a116d287e155e461453b830640d2.
Raise ArgumentError for IO.foreach with limit of 0
Makes behavior consistent with IO.readlines.
Fixes [Bug #18767]