StringIO

I’ve been playing with StringIO, and I’ve found that it doesn’t inherit
from IO.

I had thought this would be natural, as it would in theory permit us to
use a StringIO wherever an IO is used.

Comments?

Hal

Hal Fulton wrote:

I’ve been playing with StringIO, and I’ve found that it doesn’t inherit
from IO.

I had thought this would be natural, as it would in theory permit us to
use a StringIO wherever an IO is used.

Well as long as the code doesn’t check the class of it’s parameters and
just relies on duck typing it should still be possible to use a StringIO
in place of an IO object.

However, IIRC there are parts of the core language that do explicitly
check that they’re receiving a string, for speed reasons, so having
StringIO inherit from String makes more sense.

···


Mark Sparshatt

Hal Fulton wrote:

I’ve been playing with StringIO, and I’ve found that it doesn’t inherit
from IO.

I had thought this would be natural, as it would in theory permit us to
use a StringIO wherever an IO is used.

I don’t know exactly what you’re getting at, but, in watching checkins
on Ruby CVS, anything that read:

if obj.is_a? IO

was swapped to:

if obj.respond_to? :read

over the last year. I’m not saying StringIO shouldn’t inherit from IO.
Just that it’s become less important what descends from IO and more
important what implements obj#read.

_why

Hal Fulton wrote:

I’ve been playing with StringIO, and I’ve found that it doesn’t inherit
from IO.

I had thought this would be natural, as it would in theory permit us to
use a StringIO wherever an IO is used.

Agree. I ran into it recently in this form
( ruby 1.9.0 (2004-03-21) [i586-bccwin32] ):

···

#-----
require ‘stringio’

sio = StringIO.new
STDOUT.reopen(sio)
#-----

#-> C:/TEMP/rb7162.TMP:5:in `reopen’: cannot convert StringIO into IO (TypeError)

I understand Matz is a fan of StringIO.
(I can find references if he wants to argue :wink:

daz

why the lucky stiff wrote:

Hal Fulton wrote:

I’ve been playing with StringIO, and I’ve found that it doesn’t inherit
from IO.

I had thought this would be natural, as it would in theory permit us to
use a StringIO wherever an IO is used.

I don’t know exactly what you’re getting at, but, in watching checkins
on Ruby CVS, anything that read:

if obj.is_a? IO

was swapped to:

if obj.respond_to? :read

over the last year. I’m not saying StringIO shouldn’t inherit from IO.
Just that it’s become less important what descends from IO and more
important what implements obj#read.

Oh, certainly, I agree.

But I tried to use #select with a StringIO and it complained.
(If this is unreasonable, tell me, but it’s not obvious to me.)

Hal

Mark Sparshatt wrote:

Hal Fulton wrote:

I’ve been playing with StringIO, and I’ve found that it doesn’t inherit
from IO.

I had thought this would be natural, as it would in theory permit us to
use a StringIO wherever an IO is used.

Well as long as the code doesn’t check the class of it’s parameters and
just relies on duck typing it should still be possible to use a StringIO
in place of an IO object.

However, IIRC there are parts of the core language that do explicitly
check that they’re receiving a string, for speed reasons, so having
StringIO inherit from String makes more sense.

I tried a StringIO with #select and it whined at me.

But apparently it doesn’t even inherit from String, but from Data:

irb(main):001:0> require “stringio”
=> true
irb(main):002:0> StringIO.ancestors
=> [StringIO, Enumerable, Data, Object, Kernel]

Hal

Hal Fulton said:

But I tried to use #select with a StringIO and it complained.
(If this is unreasonable, tell me, but it’s not obvious to me.)

Select is based on the OS select system call which requires file numbers
to work. Since a StringIO object is not connected to an OS file number,
I’m not surprised select didn’t work for it.

···


– Jim Weirich jim@weirichhouse.org http://onestepback.org

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

Jim Weirich wrote:

Hal Fulton said:

But I tried to use #select with a StringIO and it complained.
(If this is unreasonable, tell me, but it’s not obvious to me.)

Select is based on the OS select system call which requires file numbers
to work. Since a StringIO object is not connected to an OS file number,
I’m not surprised select didn’t work for it.

OK, sure, that makes sense. I was thinking purely in terms of
delay – thinking there would always be a zero wait time.

Thanks,
Hal

Jim Weirich wrote:

Hal Fulton said:

But I tried to use #select with a StringIO and it complained.
(If this is unreasonable, tell me, but it’s not obvious to me.)

Select is based on the OS select system call which requires file numbers
to work. Since a StringIO object is not connected to an OS file number,
I’m not surprised select didn’t work for it.

Fundamentally, select() means ‘block until a read (or write) on this I/O
thing will at least partially succeed’. It would be perfectly consistent
with this meaning to implement select on a StringIO such that it returns
immediately and marks the StringIO object as ready for read and write.

Steve