re-opening STDIN after it's been closed?

Discussion in 'Ruby' started by David Vincelli, May 14, 2005.

  1. ------=_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--
     
    David Vincelli, May 14, 2005
    #1
    1. Advertising

  2. David Vincelli

    Guest

    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
     
    , May 15, 2005
    #2
    1. Advertising

  3. ------=_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, <> 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--
     
    David Vincelli, May 15, 2005
    #3
  4. David Vincelli

    Guest

    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
     
    , May 15, 2005
    #4
  5. David Vincelli

    ES Guest

    David Vincelli wrote:
    > Hi,
    >
    > On 5/14/05, <> 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(); }
     
    ES, May 15, 2005
    #5
  6. 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
     
    Stephen Lewis, May 15, 2005
    #6
  7. David Vincelli

    Tanaka Akira Guest

    In article <>,
    Stephen Lewis <> 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
     
    Tanaka Akira, May 15, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    319
    S. Justin Gengo
    Dec 19, 2005
  2. Dave Rudolf
    Replies:
    3
    Views:
    11,304
    Esmond Pitt
    Dec 31, 2003
  3. Harishankar
    Replies:
    1
    Views:
    1,514
    Harishankar
    Apr 2, 2010
  4. fniles
    Replies:
    0
    Views:
    300
    fniles
    Apr 26, 2009
  5. Matt Kruse
    Replies:
    5
    Views:
    332
    Richard Cornford
    Sep 9, 2003
Loading...

Share This Page