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
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.
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
happened.. is this a good idea and is it possible?
Thanks,
···
--
David Vincelli
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
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.
···
On Sun, May 15, 2005 at 06:20:24AM +0900, David Vincelli wrote:
--
Stephen Lewis
Hi,
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.
···
On 5/14/05, nobu.nokada@softhome.net <nobu.nokada@softhome.net> wrote:
--
David Vincelli
In article <20050515024916.GA7991@ws0.localdomain>,
Stephen Lewis <slewis@orcon.net.nz> 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
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
David Vincelli wrote:
Hi,
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/
···
On 5/14/05, nobu.nokada@softhome.net <nobu.nokada@softhome.net> wrote:
--
template<typename duck>
void quack(duck& d) { d.quack(); }