Bug #18767


IO.foreach hangs up when passes limit=0

Added by andrykonchin (Andrew Konchin) 9 months ago. Updated 5 months ago.

Target version:


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.

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #4024: IO#readlines(0) never returnClosed11/04/2010Actions

Updated by jeremyevans0 (Jeremy Evans) 8 months ago

I've submitted a pull request to fix this:

Updated by mame (Yusuke Endoh) 8 months 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) 8 months 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:'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)
Actions #4

Updated by andrykonchin (Andrew Konchin) 8 months ago

@mame (Yusuke Endoh)

I still believe that it's a compatibility issue and not a feature request or so. Could the ticket be reopened?

cc @jeremyevans0 (Jeremy Evans)

Updated by mame (Yusuke Endoh) 8 months 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).

Actions #6

Updated by mame (Yusuke Endoh) 8 months ago

  • Related to Bug #4024: IO#readlines(0) never return added

Updated by andrykonchin (Andrew Konchin) 6 months ago

Hi, just a kind reminder.

Looks like the issue is accepted but the PR was closed and the fix isn't merged.

cc @jeremyevans0 (Jeremy Evans), @mame (Yusuke Endoh)

Updated by mame (Yusuke Endoh) 6 months 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) 5 months ago

OK, let's make it raise exceptions for zero length.


Actions #10

Updated by jeremyevans (Jeremy Evans) 5 months 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]


Also available in: Atom PDF