redss has asked for the wisdom of the Perl Monks concerning the following question:

Greetings monks!

How do I implement a trap routine that will fire off a minute later?

I want a perl script that will prompt the user for input, and if the user has not responded to the prompt in a minute, an alarm routine will trigger and exit the script.

Any tips will be greatly appreciated!

Replies are listed 'Best First'.
Re: How to implement a timer in perl?
by ikegami (Patriarch) on Feb 02, 2006 at 17:10 UTC
    "... an alarm routine will trigger and exit the script."

    Update:

    Note: alarm may not work on all versions of Perl in Windows, and it may not be able to interrupt everything.

    In ActiveState Perl 5.6.1, I get "The Unsupported function alarm function is unimplemented".

    In ActiveState Perl 5.8.0, alarm was unable to interrupt $str = <STDIN>.

Re: How to implement a timer in perl?
by davorg (Chancellor) on Feb 02, 2006 at 17:11 UTC

    You answered your own question :)

    an alarm routine will trigger and exit the script
    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Ironically, the link you gave has an example of how to use alarm w/o it exiting by rerouting the encryptions, i mean the signal handler. :)
Re: How to implement a timer in perl?
by zentara (Cardinal) on Feb 02, 2006 at 18:48 UTC
    Try this snippet( from a lost node somewhere :-) ):
    #!/usr/bin/perl -w use strict; my $input = &my_stdin( prompt =>"Enter some text: ", timeout => 3, handler => \&my_alarm ); print "You entered: $input \n"; sub my_stdin { use Term::ReadKey; $| = 1; #turn buffering off so we can see our print below my %args = @_; my ($output,$key ); my $prompt = $args{'prompt'}; my $timeout = $args{'timeout'}; my $toh = $args{'handler'}; # ref to a handler $SIG{ALRM} = $toh || sub { print "Timeout\n"; exit;}; alarm($timeout); print $prompt; ReadMode 4; while(1){ if(defined($key = ReadKey(-1))){ my $val = ord $key; # 8 is backspace 10 and 13 are $output .= $key unless $val == 8 || $val == 10 || $val == 13; #echo to the screen print $key if length $output > 0; alarm($timeout); #reset the alarm #last if the user hits return last if ( $val == 10 || $val == 13); # chop one if we get a backspace if( $val == 8 ){ chop $output; print " "; print chr(8); } } } ReadMode 0; print "\n"; $output; } sub my_alarm{ print "I just died because you waited too long!\n"; exit; }
    If you want to use an event loop system, like Tk, Gtk2, or POE, you can do a neater job. Tk or Gtk2 make it trivial, but you need to be running under X or Windows. You just setup an event to be fired after the timeout you give.

    I'm not really a human, but I play one on earth. flash japh
      This is a simple example for a Tk based Timeout dialog (timeout: 5 seconds):

      #script
      use strict; use warnings; use lib qw(.); use Data::Dumper; use TimeOutDialog; my $x; TimeOutDialog::ask(\$x); if ( defined ($x) ) { print "*$x*"; } else { print "timeout\n"; }
      #dialog module

      package TimeOutDialog; use Tk; sub ask { my $mw = MainWindow->new(); my $target = shift; my $label = $mw->Label ( -text => "Please anwer my question:" )-> +pack; my $text = $mw->Entry->pack; my $button = $mw->Button ( -text => 'confirm', -command => sub { $$target = $text->get(); $mw->destroy; }, )->pack; my $id = $mw->after ( 5000, sub { $$target = undef; $mw->destroy; } ); MainLoop; } 1;


      holli, /regexed monk/
      this example was just what I needed.

      Thanks!!!

        print "What is your name Anonymous?\n"; eval { local $SIG{ALRM} = sub { die "Timeout" }; alarm 10; chomp($answer = <STDIN>); alarm 0; }; if ($@ and $@ =~ /Timeout/) { $answer = "Anonymous"; } print "Hello $answer!\n";
Re: How to implement a timer in perl?
by salva (Canon) on Feb 02, 2006 at 17:32 UTC
      Note: select only works with sockets in Windows.