JamesCOU wrote this example to go with the /UNIX Servers example elsewhere in this cookbook.

Note: There is a known problem with Term::ReadKey and some versions of Linux. It causes POE::Wheel::ReadLine to hang after the first keypress. So far the only work-around is to use Term::Visual.

If you suspect you're having this problem, try the test program at http://rt.cpan.org/Ticket/Display.html?id=3665

#!/usr/bin/perl
# This sample shows how POE::Wheel::ReadLine is used to read user
# input from the console.  It is a single-user chat system: It just
# starts a session and lets you talk to yourself.
# Use the tools everyone needs.
use strict;
use warnings;
use POE;                     # The base system.
use POE::Wheel::ReadLine;    # For reading lines from the console.

# Create a session to manage the events we want.  Each "inline_states"
# entry defines the function that will handle a corresponding event.
# Here readline_run() is triggered by the "_start" event.  The
# "got_input" event triggers the got_input_handler() function.
# Finally, readline_stop() is called to handle the "_stop" event.
# The _start and _stop events are supplied by POE to notify you just
# after a session has been created, and just before it will be
# destroyed.  They give you the opportunity to initialize things and
# shut them down.
POE::Session->create(
  inline_states => {
    _start    => \&readline_run,
    got_input => \&got_input_handler,
    _stop     => \&readline_stop,
  }
);

# Let the schizophrenia begin!  Once initial sessions have been
# created, we run them until everything is done.  The rest of this
# program is the functions that handle events.
$poe_kernel->run();
exit 0;

# This subroutine creates our ReadLine module and sends our inital
# Prompt.  ReadLine's "InputEvent" parameter specifies the event that
# will be sent when it has read a line of input or some other user
# generated exception.  As we've seen, it is triggered by POE just
# after the session is created.
sub readline_run {
  my ($heap) = $_[HEAP];
  $heap->{readline_wheel} =
    POE::Wheel::ReadLine->new(InputEvent => 'got_input');
  $heap->{readline_wheel}->get("Say Something: ");
}

# The session is about to stop.  Ensure that the ReadLine object is
# deleted, so it can place your terminal back into a sane mode.  This
# function is triggered by POE's "_stop" event.
sub readline_stop {
  delete $_[HEAP]->{readline_wheel};
}

# The input handler adds user input to an input history, displays what
# the user entered, and prompts for another line.  It also handles the
# "interrupt" exception, which is thrown by POE::Wheel::ReadLine when
# the user presses Ctrl+C.
# If you recall, POE::Session->create() has mapped the "got_input"
# event to the got_input_handler() function.  Looking back, you will
# see that POE::Wheel::ReadLine->new() is used to generate "got_input"
# events for each line of input the user enters.
# ReadLine input handlers take two arguments other than the usual
# KERNEL, HEAP, and so on.  ARG0 contains any input that was entered.
# If ARG0 is undefined, then ARG1 holds a word describing a
# user-generated exception such as "interrupt" (the user pressed
# Ctrl+C) or "cancel" (the user pressed Ctrl+G).
sub got_input_handler {
  my ($heap, $kernel, $input, $exception) = @_[HEAP, KERNEL, ARG0, ARG1];
  if (defined $input) {
    $heap->{readline_wheel}->addhistory($input);
    $heap->{readline_wheel}->put("I heard $input");
  }
  elsif ($exception eq 'interrupt') {
    $heap->{readline_wheel}->put("Goodbye.");
    delete $heap->{readline_wheel};
    return;
  }
  else {
    $heap->{readline_wheel}->put("\tException: $exception");
  }
  $heap->{readline_wheel}->get("Say Something Else: ");
}