How to redirect a string to stdin within code?

Hello all, I am trying to create a unit test for a class that reads
input
from stdin (ie. the user enters his name when starting the class). I
would
like to write a unit test that provides the input via a string.
something
like:

input = “myname”
$stdin = input
start my class that I would like to test

Any help is greatly appreciated.

Christian

On Aug 5, 2006, at 6:00 PM, Christian Seifert wrote:

Christian

require ‘stringio’

input = StringIO.new(“myname”)

$stdin = input

Logan C. wrote:

start my class that I would like to test
$stdin = input
But:

alex@pandora:~$ irb
irb(main):001:0> require ‘stringio’
=> true
irb(main):002:0> input = StringIO.new(“myname”)
=> #StringIO:0xb7a42864
irb(main):003:0> $stdin = input
=> #StringIO:0xb7a42864
/usr/lib/ruby/1.8/irb/input-method.rb:97: [BUG] Segmentation fault
ruby 1.8.4 (2005-12-24) [i486-linux]

Aborted

This is on Ubuntu Breezy. Any idea why that happens?

On 8/6/06, Alex Y. [email protected] wrote:

input = “myname”
input = StringIO.new(“myname”)
=> #StringIO:0xb7a42864
/usr/lib/ruby/1.8/irb/input-method.rb:97: [BUG] Segmentation fault
ruby 1.8.4 (2005-12-24) [i486-linux]

Aborted

This is on Ubuntu Breezy. Any idea why that happens?

Very interesting I was just trying it on my Dapper and I get similar
but
not identical behavior, see below.
However this seems an IRB issue Logans code just works fine in pure ruby

510/11 > irb
irb(main):001:0> require ‘stringio’
=> true
irb(main):002:0> input = StringIO.new(“myname”)
=> #StringIO:0xb7d2fe4c
irb(main):003:0> $stdin = input
=> #StringIO:0xb7d2fe4c
irb(main):004:0> irb(main):004:0> NameError: undefined local variable or
method `myname’ for main:Object
from (irb):4
from :0
irb(main):004:0> robert@:~/log/ruby/tests 09:43:16

and

510/12 > uname -a
Linux roma 2.6.15-19-386 #1 PREEMPT Mon Mar 20 16:46:02 UTC 2006 i686
GNU/Linux
robert@:~/log/ruby/tests 09:45:04
511/13 > ruby --version
ruby 1.8.4 (2005-12-24) [i686-linux]
robert@:~/log/ruby/tests 09:45:20
512/14 > irb --version
irb 0.9.5(05/04/13)
robert@:~/log/ruby/tes

Cheers
Robert

Alex


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

Alex Y. [email protected] writes:

However this seems an IRB issue Logans code just works fine in pure ruby
Yes… I can see why it’s not allowed in IRB (if you get rid of
stdin, how the hell would you use the console? :-), I just don’t know
why it segfaults.

Just a guess: the readline extensions directly accesses $stdin without
checking its type.

On Aug 6, 2006, at 2:59 PM, Christian N. wrote:

Alex Y. [email protected] writes:

However this seems an IRB issue Logans code just works fine in
pure ruby
Yes… I can see why it’s not allowed in IRB (if you get rid of
stdin, how the hell would you use the console? :-), I just don’t know
why it segfaults.

Just a guess: the readline extensions directly accesses $stdin without
checking its type.

I think this is probably fixed in newer versions of ruby:

% ruby -v -rstringio -e ‘log = StringIO.new(“blah”); $stdin = log;
require “irb”; IRB.start(FILE)’
ruby 1.8.3 (2005-09-28) [i386-freebsd4.11]
/usr/local/lib/ruby/1.8/irb/input-method.rb:97: [BUG] Segmentation fault
ruby 1.8.3 (2005-09-28) [i386-freebsd4.11]

Abort trap (core dumped)

versus:

% ruby -v -rstringio -e ‘log = StringIO.new(“blah”); $stdin = log;
require “irb”; IRB.start(FILE)’
ruby 1.8.4 (2006-03-04) [i686-darwin8.6.2]
Read 100 saved history commands from /Users/ryan/.irb.hist.
Saving 100 history lines to /Users/ryan/.irb.hist.
/usr/local/lib/ruby/1.8/irb/input-method.rb:97:in readline': wrong argument type StringIO (expected File) (TypeError) from /usr/local/lib/ruby/1.8/irb/input-method.rb:97:in gets’
from /usr/local/lib/ruby/1.8/irb.rb:132:in eval_input' from /usr/local/lib/ruby/1.8/irb.rb:259:in signal_status’
from /usr/local/lib/ruby/1.8/irb.rb:131:in eval_input' from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:189:in buf_input’
from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:104:in getc' from /usr/local/lib/ruby/1.8/irb/slex.rb:206:in match_io’
from /usr/local/lib/ruby/1.8/irb/slex.rb:76:in match' from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:287:in token’
from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:263:in lex' from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:234:in each_top_level_statement’
from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:230:in
each_top_level_statement' from /usr/local/lib/ruby/1.8/irb/ruby-lex.rb:229:in each_top_level_statement’
from /usr/local/lib/ruby/1.8/irb.rb:146:in eval_input' from /usr/local/lib/ruby/1.8/irb.rb:70:in start’
from /usr/local/lib/ruby/1.8/irb.rb:69:in `start’
from -e:1

Robert D. wrote:

Aborted

This is on Ubuntu Breezy. Any idea why that happens?

Very interesting I was just trying it on my Dapper and I get similar but
not identical behavior, see below.
However this seems an IRB issue Logans code just works fine in pure ruby
Yes… I can see why it’s not allowed in IRB (if you get rid of stdin,
how the hell would you use the console? :-), I just don’t know why it
segfaults.

   from (irb):4

ruby 1.8.4 (2005-12-24) [i686-linux]
Interesting. In principle, we should get the same results - the only
difference is the target processor. Allegedly.

Alex Y. [email protected] writes:

ruby 1.8.4 (2005-12-24) [i486-linux]

Aborted

This is on Ubuntu Breezy. Any idea why that happens?

Well, that particular line of the irb source is calling the method
“readline” which is defined in readline.so - that is, in C. My guess
is that it has some very specific assumptions about what type of
object it’s reading from. When I try that, I get:

esau:~$ irb
irb(main):001:0> require ‘stringio’
=> true
irb(main):002:0> stream = StringIO.new(“p [1,2,3,4]”)
=> #StringIO:0xb7c9c734
irb(main):003:0> $stdin = stream
=> #StringIO:0xb7c9c734
/usr/lib/ruby/1.8/irb/input-method.rb:97:in readline': wrong argument type StringIO (expected File) (TypeError) from /usr/lib/ruby/1.8/irb/input-method.rb:97:in gets’
from /usr/lib/ruby/1.8/irb.rb:132:in eval_input' from /usr/lib/ruby/1.8/irb.rb:259:in signal_status’
from /usr/lib/ruby/1.8/irb.rb:131:in `eval_input’
(many more lines of stacktrace omitted)

This is on my Debian testing system, so I should be running the same
binary as you are, in theory:

esau:~$ ruby -v
ruby 1.8.4 (2005-12-24) [i486-linux]

Note that “irb --noreadline” won’t have this problem, but that has
other issues (such as the fact that arrow keys don’t work any more):

esau:~$ irb --noreadline
irb(main):001:0> require ‘stringio’
=> true
irb(main):002:0> stream = StringIO.new(“p [1,2,3,4]”)
=> #StringIO:0xb7cdb7b8
irb(main):003:0> $stdin = stream
=> #StringIO:0xb7cdb7b8
irb(main):004:0> irb(main):004:0> [1, 2, 3, 4]
=> nil
irb(main):004:0> esau:~$