Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > re-opening STDIN after it's been closed?

Reply
Thread Tools

re-opening STDIN after it's been closed?

 
 
David Vincelli
Guest
Posts: n/a
 
      05-14-2005
------=_Part_13322_3417944.1116105604111
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

here's a summary of a script I just wrote:

while (true) do
puts "Make your selection from the list below: \n\n"
puts "a) foo\n"
puts "b) bar\n\n"
gets
handle_action($_)
end

handle_action does stuff that isn't relevant to my question.

The program works fine except when I hit CTRL-D. After I hit CTRL-D, the=20
program runs in an endless loop and seems to skip over the gets statement.=
=20
Doesn't look good, I can't even break out of it (CTRL-C). Of course CTRL-D=
=20
indicates end of file. My guess is that this closes STDIN.

I just thought of a "work around", consisting of inserting

exit unless $_

after the gets statement

I think it might be better to simply re-open STDIN as if nothing had=20
happened.. is this a good idea and is it possible?

Thanks,

--=20
David Vincelli

------=_Part_13322_3417944.1116105604111--


 
Reply With Quote
 
 
 
 
nobu.nokada@softhome.net
Guest
Posts: n/a
 
      05-15-2005
Hi,

At Sun, 15 May 2005 06:20:24 +0900,
David Vincelli wrote in [ruby-talk:142655]:
> while (true) do
> puts "Make your selection from the list below: \n\n"
> puts "a) foo\n"
> puts "b) bar\n\n"
> gets
> handle_action($_)
> end


You should alwasy check if get succeeded.

prompt = <<PROMPT
Make your selection from the list below: \n
a) foo
b) bar

PROMPT

while (print(prompt); ans = gets)
handle_action(ans)
end

Or even better if you can use readline:

while ans = readline(prompt)
handle_action(ans)
end

> I think it might be better to simply re-open STDIN as if nothing had
> happened.. is this a good idea and is it possible?


No way to do it. If you believe STDIN is connected to tty, you
may want to do STDIN.reopen("/dev/tty").

--
Nobu Nakada


 
Reply With Quote
 
 
 
 
David Vincelli
Guest
Posts: n/a
 
      05-15-2005
------=_Part_13678_6534629.1116121419114
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi,

On 5/14/05, http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:
>=20
> You should alwasy check if get succeeded.
>=20
> prompt =3D <<PROMPT
> Make your selection from the list below: \n
> a) foo
> b) bar
>=20
> PROMPT
>=20
> while (print(prompt); ans =3D gets)
> handle_action(ans)
> end



I haven't tried this yet but it's definately better than what I originally=
=20
posted.

> Or even better if you can use readline:
>=20
> while ans =3D readline(prompt)
> handle_action(ans)
> end



But I did try this. I don't think your usage of readline is correct. ri=20
tells me that readline takes a single parameter and it's the line seperator=
=20


I suppose you meant this:

while (print prompt; ans =3D readline)
handle_action(ans)
end

No way to do it. If you believe STDIN is connected to tty, you
> may want to do STDIN.reopen("/dev/tty").



Thanks for the tip. I'll stick to the fixed up while loop.

--=20
David Vincelli

------=_Part_13678_6534629.1116121419114--


 
Reply With Quote
 
nobu.nokada@softhome.net
Guest
Posts: n/a
 
      05-15-2005
Hi,

At Sun, 15 May 2005 10:44:00 +0900,
David Vincelli wrote in [ruby-talk:142672]:
> > Or even better if you can use readline:
> >
> > while ans = readline(prompt)
> > handle_action(ans)
> > end

>
>
> But I did try this. I don't think your usage of readline is correct. ri
> tells me that readline takes a single parameter and it's the line seperator.


Sorry, I forgot "Readline." before it.

require 'readline'
while ans = Readline.readline(prompt)
handle_action(ans)
end

--
Nobu Nakada


 
Reply With Quote
 
ES
Guest
Posts: n/a
 
      05-15-2005
David Vincelli wrote:
> Hi,
>
> On 5/14/05, (E-Mail Removed) <(E-Mail Removed)> wrote:
>
>>You should alwasy check if get succeeded.
>>
>>prompt = <<PROMPT
>>Make your selection from the list below: \n
>>a) foo
>>b) bar
>>
>>PROMPT
>>
>>while (print(prompt); ans = gets)
>>handle_action(ans)
>>end

>
>
>
> I haven't tried this yet but it's definately better than what I originally
> posted.
>
>
>>Or even better if you can use readline:
>>
>>while ans = readline(prompt)
>>handle_action(ans)
>>end

>
>
>
> But I did try this. I don't think your usage of readline is correct. ri
> tells me that readline takes a single parameter and it's the line seperator.
>
>
> I suppose you meant this:
>
> while (print prompt; ans = readline)
> handle_action(ans)
> end
>
> No way to do it. If you believe STDIN is connected to tty, you
>
>>may want to do STDIN.reopen("/dev/tty").

>
>
>
> Thanks for the tip. I'll stick to the fixed up while loop.
>


Have you taken a look at some libraries to help you with this?

Cmd[1] is a simple tool for creating command-line oriented interpreters
(think of sqlite/svnadmin/mysqladmin etc.)

HighLine[2] provides a higher-level interface to the command-line from
your script.

E

[1] http://rubyforge.org/projects/cmd/
[2] http://rubyforge.org/projects/highline/

--
template<typename duck>
void quack(duck& d) { d.quack(); }


 
Reply With Quote
 
Stephen Lewis
Guest
Posts: n/a
 
      05-15-2005
On Sun, May 15, 2005 at 06:20:24AM +0900, David Vincelli wrote:

> The program works fine except when I hit CTRL-D. After I hit CTRL-D, the
> program runs in an endless loop and seems to skip over the gets statement.
> Doesn't look good, I can't even break out of it (CTRL-C). Of course CTRL-D
> indicates end of file. My guess is that this closes STDIN.

<snip>
> I think it might be better to simply re-open STDIN as if nothing had
> happened.. is this a good idea and is it possible?



I don't think it actually closes stdin - try this:

while true
puts "type something"
$stdin.gets
if $stdin.closed?
puts "it's closed"
break
elsif $stdin.eof?
puts "apparently eof"
$stdin.seek( 0, IO::SEEK_CUR )
end
end

Ruby doesn't seem to have an equivalent to clearerr(3), which might
help here - but a successful seek is supposed to reset the eof flag,
though it's fairly ugly, and isn't guaranteed to succeed (it'll
probably break with pipes for one thing). You might try an
ungetc/getc pair as another workaround, but there's probably a much
nicer way.

--
Stephen Lewis


 
Reply With Quote
 
Tanaka Akira
Guest
Posts: n/a
 
      05-15-2005
In article <(E-Mail Removed)>,
Stephen Lewis <(E-Mail Removed)> writes:

> Ruby doesn't seem to have an equivalent to clearerr(3), which might
> help here - but a successful seek is supposed to reset the eof flag,
> though it's fairly ugly, and isn't guaranteed to succeed (it'll
> probably break with pipes for one thing). You might try an
> ungetc/getc pair as another workaround, but there's probably a much
> nicer way.


Since 1.8.3, Ruby calls clearerr(3) before getc(3) in IO#gets. So you
don't need to clear the eof flag in this case.
--
Tanaka Akira


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
peek at stdin, flush stdin Johnathan Doe C Programming 5 05-17-2013 04:30 PM
How to pass stdin of a C++ program to the stdin of a process createdwith ShellExecute() Ben C Programming 2 08-29-2009 09:47 PM
STDIN, OUT, ERR and $stdin, out, err - Differences? Terry Cooper Ruby 7 06-09-2009 05:48 AM
Reading from stdin then launching a program that reads from stdin strange behaviour Stefano Sabatini Perl Misc 6 07-29-2007 10:38 PM
Reading stdin once confuses second stdin read Charlie Zender C Programming 6 06-21-2004 01:39 PM



Advertisments