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

require 'stringio'

input = StringIO.new("myname")

$stdin = input

···

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

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

Logan Capaldo wrote:

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

require 'stringio'

input = StringIO.new("myname")

$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 Aug 5, 2006, at 6:00 PM, Christian Seifert wrote:

--
Alex

Logan Capaldo wrote:
>
>> 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
>>
>
> require 'stringio'
>
> input = StringIO.new("myname")
>
> $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?

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
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

···

On 8/6/06, Alex Young <alex@blackkettle.org> wrote:

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

        from :0

--

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 Young <alex@blackkettle.org> writes:

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?

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:~$

Robert Dober wrote:
<snip>

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?

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.

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]

Interesting. In principle, we should get the same results - the only difference is the target processor. Allegedly.

···

--
Alex

Alex Young <alex@blackkettle.org> 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.

···

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

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

···

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

Alex Young <alex@blackkettle.org> 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.