Project

General

Profile

Actions

Bug #18770

closed

Inconsistent behavior of IO/StringIO's each methods when called with nil as a separator, limit and chomp: true

Added by andrykonchin (Andrew Konchin) over 2 years ago. Updated over 2 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:108502]

Description

IO's and StringIO's #each method (and similar ones - #gets, #readline etc) behave in a different way in the following case:

  • separator is nil
  • limit is passed
  • chomp: true passed

In this case StringIO#each removes trailing \n but IO#each does not:

StringIO.new("abc\n\ndef\n").each(nil, 2, chomp: true).to_a
#=> ["ab", "c", "\nd", "ef", ""]

File.open('chomp.txt').each(nil, 2, chomp: true).to_a
#=> ["ab", "c\n", "\nd", "ef", "\n"]

The file has the same content:

File.read('chomp.txt');
#=> "abc\n\ndef\n"

Expected behavior - both methods return the same result.


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #18768: Inconsistent behavior of IO, StringIO and String each_line methods when return paragraph and chomp: true passedClosedActions
Actions #1

Updated by jeremyevans0 (Jeremy Evans) over 2 years ago

  • Related to Bug #18768: Inconsistent behavior of IO, StringIO and String each_line methods when return paragraph and chomp: true passed added

Updated by jeremyevans0 (Jeremy Evans) over 2 years ago

I think both IO#each and StringIO#each behavior is wrong when combining nil with chomp. My opinion is that a nil separator means there is no separator at all, and therefore chomp should either raise an error or be ignored if nil is the separator. Assuming that ignoring chomp is desired behavior for nil separator, it follows:

  • IO#each behavior for nil and chomp with a limit is correct. However, IO#each for nil and chomp without a limit is not, since it removes a final line separator.

  • StringIO#each behavior for nil and chomp is wrong, regardless of whether a limit is used.

This issue is related to String#each_line, but the nil and chomp combination there is handled correctly, not removing any characters (it doesn't support limit).

Note that Ruby has current tests for the IO#each behavior for nil and chomp without limit removing the trailing line separator. So the current behavior for that is definitely expected, though I consider it undesirable.

I've added PRs for Ruby (https://github.com/ruby/ruby/pull/5959) and StringIO (https://github.com/ruby/stringio/pull/28) for this.

Actions #3

Updated by jeremyevans (Jeremy Evans) over 2 years ago

  • Status changed from Open to Closed

Applied in changeset git|adaaf12857ce41d35b282e3fb5aa330934ce45c6.


[ruby/stringio] Ignore chomp keyword for nil separator

nil separator means no separator at all, so nothing should be
chomped.

Partial fix for Ruby [Bug #18770]

https://github.com/ruby/stringio/commit/feaa2ec631

Actions #4

Updated by jeremyevans0 (Jeremy Evans) over 2 years ago

  • Status changed from Closed to Open

Updated by mame (Yusuke Endoh) over 2 years ago

We discussed this at the dev meeting, and @matz (Yukihiro Matsumoto) agreed with @jeremyevans0 (Jeremy Evans).

Actions #6

Updated by jeremyevans (Jeremy Evans) over 2 years ago

  • Status changed from Open to Closed

Applied in changeset git|04f86ad0b5d2fe4711ff300d855228a6aed55f33.


Do not chomp trailing line separator IO#each with nil separator and chomp

nil separator means no sepator, so chomp should not remove a line
separator.

Partially Fixes [Bug #18770]

Actions #7

Updated by jeremyevans0 (Jeremy Evans) over 2 years ago

  • Status changed from Closed to Open
Actions #8

Updated by jeremyevans (Jeremy Evans) over 2 years ago

  • Status changed from Open to Closed

Applied in changeset git|7223c0da152114c84e1c4261a282faaea21646fb.


Do not chomp trailing line separator IO#each with nil separator and chomp

nil separator means no sepator, so chomp should not remove a line
separator.

Partially Fixes [Bug #18770]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0