Project

General

Profile

Bug #2449

StringIO#ungetc behavior is contrary to its spec

Added by vvs (Vladimir Sizikov) over 9 years ago. Updated about 8 years ago.

Status:
Assigned
Priority:
Normal
Target version:
-
ruby -v:
ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32]
[ruby-core:27074]

Description

=begin
The spec for StringIO#ungetc() states: "Pushing back behind the beginning of the buffer string is not possible. Nothing will be done if such an attempt is made.".

But: ruby -rstringio -e "io = StringIO.new(''); io.ungetc(?1); io.ungetc(?2); p io.gets"

will print "21" instead of nil. Please also note that rbx and JRuby correctly return nil. Also, there is a stringio test that actually enforses the wrong behavior (test_ungetc), but with the comment: bug? :)

Here's how different MRI versions behave: Looks like MRI 1.8.6 is the correct one:

Z:\work\ruby18-dev.git>pik ruby -rstringio -e "io=StringIO.new('');io.ungetc(?1);io.ungetc(?2); p io.gets"
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

nil

ruby 1.8.6 (2009-08-04 patchlevel 383) [i386-mingw32]

"21"

ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]

nil

ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32]

"21"

ruby 1.9.0 (2008-06-20 revision 17482) [i386-mswin32]

"21"

ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-mswin32]

"21"

ruby 1.9.1p0 (2009-01-30 revision 21907) [x64-mswin64_80]

"21"

ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-mswin32]

"21"

ruby 1.9.2dev (2009-07-18) [i386-mswin32]

"21"

ruby 1.9.2dev (2009-11-12 trunk 25723) [i386-mingw32]

"21"
=end

History

#1

Updated by matz (Yukihiro Matsumoto) over 9 years ago

=begin
Hi,

In message "Re: [ruby-core:27074] [Bug #2449] StringIO#ungetc behavior is contrary to its spec"
on Mon, 7 Dec 2009 05:12:42 +0900, Vladimir Sizikov redmine@ruby-lang.org writes:
|
|The spec for StringIO#ungetc() states: "Pushing back behind the beginning of the buffer string is not possible. Nothing will be done if such an attempt is made.".

Spec has changed for 1.9:

call-seq:
strio.ungetc(string) -> nil

Pushes back one character (passed as a parameter) onto strio
such that a subsequent buffered read will return it. There is no
limitation for multiple pushbacks including pushing back behind the
beginning of the buffer string.

1.8.7 inherits the behavior from 1.9, but spec statement has not been
updated.

                        matz.

=end

#2

Updated by nahi (Hiroshi Nakamura) over 9 years ago

=begin
Hi,

On Mon, Dec 7, 2009 at 08:02, Yukihiro Matsumoto matz@ruby-lang.org wrote:

Spec has changed for 1.9:

 call-seq:
  strio.ungetc(string)   -> nil

 Pushes back one character (passed as a parameter) onto strio
 such that a subsequent buffered read will return it.  There is no
 limitation for multiple pushbacks including pushing back behind the
 beginning of the buffer string.

Yes.

1.8.7 inherits the behavior from 1.9, but spec statement has not been
updated.

Do you mean this IO change should be backported?

0% ruby19 -ve 'r,w = IO.pipe; r.ungetc(?a); p r.getc'
ruby 1.9.2dev (2009-12-08 trunk 26049) [i686-linux]
"a"
0% ruby -ve 'r,w = IO.pipe; r.ungetc(?a); p r.getc'
ruby 1.8.8dev (2009-12-07 revision 25983) [i686-linux]
-e:1:in `ungetc': unread stream (IOError)
from -e:1
1%

=end

#3

Updated by nahi (Hiroshi Nakamura) over 9 years ago

=begin
Hi,

On Mon, Dec 7, 2009 at 08:02, Yukihiro Matsumoto matz@ruby-lang.org wrote:

Spec has changed for 1.9:

 call-seq:
  strio.ungetc(string)   -> nil

 Pushes back one character (passed as a parameter) onto strio
 such that a subsequent buffered read will return it.  There is no
 limitation for multiple pushbacks including pushing back behind the
 beginning of the buffer string.

Yes.

1.8.7 inherits the behavior from 1.9, but spec statement has not been
updated.

Do you mean this IO change (multiple pushbacks and behind the
beginning) should be backported to 1.8?

0% ruby19 -ve 'r,w = IO.pipe; r.ungetc(?a); p r.getc'
ruby 1.9.2dev (2009-12-08 trunk 26049) [i686-linux]
"a"
0% ruby -ve 'r,w = IO.pipe; r.ungetc(?a); p r.getc'
ruby 1.8.8dev (2009-12-07 revision 25983) [i686-linux]
-e:1:in `ungetc': unread stream (IOError)
from -e:1
1%

// NaHi

=end

#4

Updated by naruse (Yui NARUSE) over 9 years ago

  • Category set to ext
  • Status changed from Open to Assigned
  • Assignee set to matz (Yukihiro Matsumoto)

=begin

=end

#5

Updated by mame (Yusuke Endoh) about 9 years ago

=begin
Hi,

Do you mean this IO change (multiple pushbacks and behind the
beginning) should be backported to 1.8?

I move this ticket to 1.8.
But it may be difficult for 1.8 that uses C's stdio to implement IO.

--
Yusuke Endoh mame@tsg.ne.jp
=end

#6

Updated by nahi (Hiroshi Nakamura) about 9 years ago

=begin
Hi,

On Wed, Apr 28, 2010 at 21:34, Yusuke Endoh redmine@ruby-lang.org wrote:

Do you mean this IO change (multiple pushbacks and behind the
beginning) should be backported to 1.8?

I move this ticket to 1.8.
But it may be difficult for 1.8 that uses C's stdio to implement IO.

Yes. So I think that the following is not correct.

| There is no
| limitation for multiple pushbacks including pushing back behind the
| beginning of the buffer string.

No one seem to have a correct answer. Let's accept RubySpec's test
assertion for 1.8.

Regards,
// NaHi

=end

#7

Updated by mame (Yusuke Endoh) about 9 years ago

=begin
Hi,

2010/4/28 NAKAMURA, Hiroshi nakahiro@gmail.com:

On Wed, Apr 28, 2010 at 21:34, Yusuke Endoh redmine@ruby-lang.org wrote:

Do you mean this IO change (multiple pushbacks and behind the
beginning) should be backported to 1.8?

I move this ticket to 1.8.
But it may be difficult for 1.8 that uses C's stdio to implement IO.

Yes. So I think that the following is not correct.

| ?There is no
| ?limitation for multiple pushbacks including pushing back behind the
| ?beginning of the buffer string.

The above spec is valid just for StringIO#ungetc. It is not directly
connected to IO#ungetc. Do you mean StringIO#ungetc should behave
the same as IO#ungetc, even in such corner case?

My honest opinion is, this behavior should be considered implementation-
defined, not a spec, not only in 1.8 but also in 1.9. User should not
depend on such a "corner case" behavior :-)

--
Yusuke Endoh mame@tsg.ne.jp

=end

#8

Updated by nahi (Hiroshi Nakamura) about 9 years ago

=begin
Hi,

On Wed, Apr 28, 2010 at 23:23, Yusuke ENDOH mame@tsg.ne.jp wrote:

Do you mean this IO change (multiple pushbacks and behind the
beginning) should be backported to 1.8?

I move this ticket to 1.8.
But it may be difficult for 1.8 that uses C's stdio to implement IO.

Yes. So I think that the following is not correct.

| ?There is no
| ?limitation for multiple pushbacks including pushing back behind the
| ?beginning of the buffer string.

The above spec is valid just for StringIO#ungetc.

I don't see the reason. As far as I understand, Matz indicated 'This
spec is right for StringIO because its the spec of IO'. The latter
part is true for 1.9, but not true for 1.8 (and must be hard to be
true as you know). So still the former part couldn't be true for 1.8.

We don't have much interest to this trivial behavior. Can't you accept
my proposal? It requires less work for changes. :-)

Regards,
// NaHi

=end

#9

Updated by mame (Yusuke Endoh) about 9 years ago

=begin
Hi,

Sorry I have not read mails in a few days because of trip.

2010/4/29 NAKAMURA, Hiroshi nakahiro@gmail.com:

We don't have much interest to this trivial behavior. Can't you accept
my proposal? It requires less work for changes. :-)

What is your proposal?

I thought you proposed a backport of the behavior (multiple pushbacks
and behind the beginning) to general IO. [ruby-core:27114]
I guess it is difficult, but I'm not against it. [ruby-core:29842]

Are you proposing the revert of 1.8 StringIO's new behavior?
Even if so, I'm also not against it. Please ask knu (1.8 maintainer)
or matz.

Anyway, I have no right to accept your proposal :-)

--
Yusuke Endoh mame@tsg.ne.jp

=end

#10

Updated by nahi (Hiroshi Nakamura) about 9 years ago

=begin
Hi,

On Mon, May 3, 2010 at 15:46, Yusuke ENDOH mame@tsg.ne.jp wrote:

2010/4/29 NAKAMURA, Hiroshi nakahiro@gmail.com:

We don't have much interest to this trivial behavior. Can't you accept
my proposal? It requires less work for changes. :-)

What is your proposal?

See [ruby-core:29848]:

Let's accept RubySpec's test assertion for 1.8.

And the original article stated:

The spec for StringIO#ungetc() states: "Pushing back behind the
beginning of the buffer string is not possible. Nothing will be done
if such an attempt is made.".

I thought you proposed a backport of the behavior (multiple pushbacks
and behind the beginning) to general IO.  [ruby-core:27114]

Not at all.

Regards,
// NaHi

=end

Also available in: Atom PDF