POE, The Perl Object Environment can be thought of as a tiny modular operating system. One or more POE programs or instances can be run concurrently and are generally well suited for cooperative multitasking. The POE package consists of namespaces and abstractions that guide future development of POE in an open-ended CPAN-style convention.
The informal architecture consists of a set of layers with a kernel on the bottom. This tiny kernel represents the events layer which operates as the main loop of each running POE instance. The first call is to the "event dispatcher" - POE::Kernel.
The POE::Kernel namespace contains a suite of functions which are plugged into the kernel itself. These loop abstractions are designed after POE's standardized event loop bridge interface - POE::Loop. These can be mixed and matched as needed to provide runtime services and a lean facility for interprocess communication. The basic functions are POE::Loop::Event, POE::Loop::Poll and POE::Loop::Select. Also available are POE::Loop::Tk and POE::Loop::Gtk which offer hooks into other loop bridges in the external environment. If that isn't enough, the POE::Loop kernel abstraction provides reusable signal callbacks, time or alarm callbacks, and filehandle activity callbacks as well as administrative functions such as initializing, executing, and finalizing event loops.
There is also a higher level packaging framework - POE::Macro and a debugging utility for testing them called POE::Preprocessor. This framework has yielded POE::Macro::UseBytes.
The Running Kernel operates through primordial finite state machines constructed from another set of abstractions ruled by the POE::Session architecture. A POE::Session is almost trivially defined as a map of events to the functions, class methods, and/or object methods that handle them. POE::Session objects also contain a storage space shared by all its event handlers, called a heap. Any way you slice them the states are solidly identified and clearly defined.
A more featureful event handler is a POE::Session subclass called POE::NFA - an event-driven Nondeterministic finite Automaton (a smarter finite state machine). This event handler moves from one strictly defined state to another as events, polls, user selections, or other external events require. This state machine acts to encapsulate a wide range of generic event driven threads allowing much tighter tracking along the execution path than the relatively informal POE::Session.
The Kernel's next requirement is for Input-Output handlers that exist in a single I/O layer called Wheels. Wheels initiate actions, handle their resulting low-level events, and produce higher-level events for the sessions that use them. Wheels, like Sessions and Loops are built from a uniform set of abstractions - POE::Wheel - that sit on top of the Kernel. There are seven highly specialized and well-defined Wheels in POE's base distribution:
Drivers do the actual work of reading and writing filehandles. They are built according to the less abstract definitions contained in the POE::Driver module. The main driver implemented at the time of this writing is POE::Driver::SysRW - a universal filehandle reader/writer designed especially for POE::Wheel::ReadWrite.
The next layer, built from POE::Filter and probably the focus of most Perl Obfuscation Efficianados (see POE #POE Humor below), is the POE::Filter set:
"Filters translate between raw streams and cooked chunks of tasty dada." per `sungo'
see POE at CPAN for the complete list
Several larger packages have been written in POE according to the POE::Component documentation. These are event-driven modules, many of which act as little daemons that provide services to larger packages to which they belong. Some of them facilitate higher-level communications between modules, especially stand-alone applications that need to remain independent from the main distribution of Perl.
In general, POE Components are ready-made high level procedures that perform specific large tasks. A few examples:
"POE Components tend to be highly reusable libraries that handle tedious tasks, freeing programmers to focus on more interesting things. This should be true for any library, though."
Edited: 2021-06-18 14:30:57