https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112018-02-20T06:25:04ZRuby Issue Tracking SystemRuby master - Bug #14400: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behaviorhttps://bugs.ruby-lang.org/issues/14400?journal_id=704642018-02-20T06:25:04Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>akr (Akira Tanaka)</i></li></ul> Ruby master - Bug #14400: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behaviorhttps://bugs.ruby-lang.org/issues/14400?journal_id=704702018-02-20T07:23:09Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Feedback</i></li></ul><p>Basically, ungetbyte/ungetc works if there is enough space in the IO buffer.</p>
<p>Since the IO buffer is not dynamically extended and<br>
the buffer size is internal behavior,<br>
it is very small guarantee that we have enough space:<br>
(1) There is 1 byte space at beginning and<br>
(2) there is 1 byte space just after reading some data.</p>
<p>Note that current implementation of ungetbyte allocates<br>
enough buffer to save given string if IO buffer is not allocated yet.<br>
(This is the reason we can ungetbyte large data at beginning.)</p>
<p>Some idea:</p>
<ul>
<li>describe the above guarantee in the document.</li>
<li>refine error message: "ungetbyte failed" to "ungetbyte: IO buffer space not enough"</li>
</ul>
<p>Also, I found a situation that we cannot push back one (multibyte) character, now.</p>
<pre><code>% ./ruby -e 'print "a" * 1024*32'|./ruby -e 'p STDIN.getc; STDIN.ungetc "\u3042"'
"a"
Traceback (most recent call last):
1: from -e:1:in `<main>'
-e:1:in `ungetc': ungetbyte failed (IOError)
</code></pre>
<p>I'm not sure what we can here.</p> Ruby master - Bug #14400: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behaviorhttps://bugs.ruby-lang.org/issues/14400?journal_id=704962018-02-20T13:03:53Zakr (Akira Tanaka)akr@fsij.org
<ul></ul><p>Even worse, I found an example which ungetc can not push back<br>
a character which just returned by getc.</p>
<pre><code>% ./ruby -e 'print "a" * (1024*8-2) + "\n\u0080" + "b" * (1024*8-1)'|
./ruby -e 'STDIN.gets; c = STDIN.getc; p c; STDIN.ungetc(c)'
"\u0080"
Traceback (most recent call last):
1: from -e:1:in `<main>'
-e:1:in `ungetc': ungetbyte failed (IOError)
</code></pre>
<p>So, current implementation guarantee that only one "byte"<br>
can be pushed back after reading data.<br>
It is not enough to push back a multibyte character.</p>
<pre><code>% ./ruby -v
ruby 2.6.0dev (2018-02-20 trunk 62490) [x86_64-linux]
</code></pre> Ruby master - Bug #14400: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behaviorhttps://bugs.ruby-lang.org/issues/14400?journal_id=704972018-02-20T14:13:42ZEregon (Benoit Daloze)
<ul></ul><p>Could the buffer grow automatically to allow pushing multiple bytes/characters back?<br>
That's the current implementation in TruffleRuby and Rubinius, the buffer grows on ungetbyte/ungetc if there is not enough space.<br>
Then the semantics for the user would be much simpler.</p> Ruby master - Bug #14400: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behaviorhttps://bugs.ruby-lang.org/issues/14400?journal_id=705052018-02-21T00:26:06Zakr (Akira Tanaka)akr@fsij.org
<ul></ul><p>I think it is possible to glow the IO read buffer (rbuf) if it is properly locked.</p>
<p>Since the IO buffer is modified without GVL<br>
(to avoid whole process blocking),<br>
glowing (realloc) the buffer without lock is too dangerous.</p>
<p>It seems rb_io_t has no lock for rbuf, now.<br>
(I guess write_lock is not for the lock for rbuf.)</p> Ruby master - Bug #14400: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behaviorhttps://bugs.ruby-lang.org/issues/14400?journal_id=918102021-05-04T18:25:56Zjeremyevans (Jeremy Evans)code@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Feedback</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="Fix documentation for IO#unget{byte,c} Fixes [Bug #14400]" href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/c809a8cae8c2c8e64fd2d1b0fe8571faf443b8cd">git|c809a8cae8c2c8e64fd2d1b0fe8571faf443b8cd</a>.</p>
<hr>
<p>Fix documentation for IO#unget{byte,c}</p>
<p>Fixes [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behavior (Closed)" href="https://bugs.ruby-lang.org/issues/14400">#14400</a>]</p> Ruby master - Bug #14400: IO#ungetc and IO#ungetbyte documentation is inconsistent with the behaviorhttps://bugs.ruby-lang.org/issues/14400?journal_id=918382021-05-05T15:06:24ZEregon (Benoit Daloze)
<ul></ul><p>Thank you for the doc update!</p>