This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: PNGgraph,  Next: PNGgraph/colour,  Prev: PML/Storable,  Up: Module List

Graph Plotting Module for Perl 5
********************************

NAME
====

   PNGgraph - Graph Plotting Module for Perl 5

SYNOPSIS
========

   use PNGgraph::moduleName;

DESCRIPTION
===========

   *PNGgraph* is a *perl5* module to create and display PNG output for a
graph.  The following classes for graphs with axes are defined:

`PNGgraph::lines'
     Create a line chart.

`PNGgraph::bars'
     Create a bar chart.

`PNGgraph::points'
     Create an chart, displaying the data as points.

`PNGgraph::linespoints'
     Combination of lines and points.

`PNGgraph::area'
     Create a graph, representing the data as areas under a line.

`PNGgraph::mixed'
     Create a mixed type graph, any combination of the above. At the moment
     this is fairly limited. Some of the options that can be used with some
     of the individual graph types won't work very well. Multiple bar
     graphs in a mixed graph won't display very nicely.

   Additional types:

`PNGgraph::pie'
     Create a pie chart.

EXAMPLES
========

   See the samples directory in the distribution.

USAGE
=====

   Fill an array of arrays with the x values and the values of the data
sets.  Make sure that every array is the same size, otherwise *PNGgraph*
will complain and refuse to compile the graph.

     @data = (
         ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
         [    1,    2,    5,    6,    3,  1.5,    1,     3,     4]
         [ sort { $a <=> $b } (1, 2, 5, 6, 3, 1.5, 1, 3, 4) ]
     );

   If you don't have a value for a point in a certain dataset, you can use
undef, and *PNGgraph* will skip that point.

   Create a new *PNGgraph* object by calling the new operator on the graph
type you want to create (*chart* is *bars, lines, points, linespoints* or
*pie*).

     $my_graph = new PNGgraph::chart( );

   Set the graph options.

     $my_graph->set(
         x_label           => 'X Label',
         y_label           => 'Y label',
         title             => 'Some simple graph',
         y_max_value       => 8,
         y_tick_number     => 8,
         y_label_skip      => 2
     );

   Output the graph

     $my_graph->plot_to_png( "sample01.png", \@data );

METHODS AND FUNCTIONS
=====================

Methods for all graphs
----------------------

new PNGgraph::chart([width,height])
     Create a new object $graph with optional width and heigth.  Default
     width = 400, default height = 300. *chart* is either *bars, lines,
     points, linespoints, area* or *pie*.

set_text_clr( *colour name* )
     Set the colour of the text. This will set the colour of the titles,
     labels, and axis labels to *colour name*. Also see the options
     *textclr*, *labelclr* and *axislabelclr*.

set_title_font( fontname )
     Set the font that will be used for the title of the chart.  Possible
     choices are defined in *Note GD: GD,.  *NB.* If you want to use this
     function, you'll need to use *Note GD: GD,. At some point I'll
     rewrite this, so you can give this a number from 1 to 4, or a string
     like 'large' or 'small'. On the other hand, I might not, if Thomas
     Boutell decides to support more fonts.

plot( *\@data* )
     Plot the chart, and return the PNG data.

plot_to_png( filename, *\@data* )
     Plot the chart, and write the PNG data to filename.

set( key1 => value1, key2 => value2 .... )
     Set chart options. See OPTIONS section.

Methods for Pie charts
----------------------

set_label_font( fontname )
set_value_font( fontname )
     Set the font that will be used for the label of the pie or the values
     on the pie.  Possible choices are defined in *Note GD: GD,.  See also
     *set_title_font*.

Methods for charts with axes.
-----------------------------

set_x_label_font ( *font name* )
set_y_label_font ( *font name* )
set_x_axis_font ( *font name* )
set_y_axis_font ( *font name* )
     Set the font for the x and y axis label, and for the x and y axis
     value labels.  See also *set_title_font*.

OPTIONS
=======

Options for all graphs
----------------------

pngx, pngy
     The width and height of the png file in pixels Default: 400 x 300.
     *NB* At the moment, these are read-only options. If you want to set
     the size of a graph, you will have to do that with the new method.

t_margin, b_margin, l_margin, r_margin
     Top, bottom, left and right margin of the PNG. These margins will be
     left blank.  Default: 0 for all.

logo
     Name of a logo file. This should be a PNG file.  Default: no logo.

logo_resize, logo_position
     Factor to resize the logo by, and the position on the canvas of the
     logo. Possible values for logo_position are 'LL', 'LR', 'UL', and
     'UR'.  (lower and upper left and right).  Default: 'LR'.

transparent
     If set to a true value, the produced PNG will have the background
     colour marked as transparent (see also option *bgclr*).  Default: 1.

interlaced
     If set to a true value, the produced PNG will be interlaced.
     Default: 1.

bgclr, fgclr, textclr, labelclr, axislabelclr, accentclr
     Background, foreground, text, label, axis label and accent colours.

dclrs (short for datacolours)
     This controls the colours for the bars, lines, markers, or pie slices.
     This should be a reference to an array of colour names as defined in
     *Note PNGgraph/colour: PNGgraph/colour, (`perldoc PNGgraph::colour'
     for the names available).

          $graph->set( dclrs => [ qw(green pink blue cyan) ] );

     The first (fifth, ninth) data set will be green, the next pink, etc.
     Default: [ qw(lred lgreen lblue lyellow lpurple cyan lorange) ]

Options for graphs with axes.
-----------------------------

   options for *bars*, lines, points, *linespoints* and area charts.

long_ticks, tick_length
     If *long_ticks* is a true value, ticks will be drawn the same length
     as the axes.  Otherwise ticks will be drawn with length
     *tick_length*. if *tick_length* is negative, the ticks will be drawn
     outside the axes.  Default: long_ticks = 0, tick_length = 4.

x_ticks
     If x_ticks is a true value, ticks will be drawm for the x axis.
     These ticks are subject to the values of *long_ticks* and
     *tick_length*.  Default: 1.

y_tick_number
     Number of ticks to print for the Y axis. Use this, together with
     *y_label_skip* to control the look of ticks on the y axis.  Default:
     5.

y_number_format
     This can be either a string, or a reference to a subroutine. If it is
     a string, it will be taken to be the first argument to an sprintf,
     with the value as the second argument:

          $label = sprintf( $s->{y_number_format, $value );

     If it is a code reference, it will be executed with the value as the
     argument:

          $label = &{$s->{y_number_format}}($value);

     This can be useful, for example, if you want to reformat your values
     in currency, with the - sign in the right spot. Something like:

          sub y_format
          {
              my $value = shift;
              my $ret;

          if ($value >= 0)
          {
              $ret = sprintf("\$%d", $value * $refit);
          }
          else
          {
              $ret = sprintf("-\$%d", abs($value) * $refit);
          }

          return $ret;
              }

          $my_graph->set( 'y_number_format' => \&y_format );

     (Yes, I know this can be much shorter and more concise)

     Default: undef.

x_label_skip, y_label_skip
     Print every x_label_skipth number under the tick on the x axis, and
     every *y_label_skip*th number next to the tick on the y axis.
     Default: 1 for both.

x_all_ticks
     Force a print of all the x ticks, even if x_label_skip is set to a
     value Default: 0.

x_label_position
     Controls the position of the X axis label (title). The value for this
     should be between 0 and 1, where 0 means aligned to the left, 1 means
     aligned to the right, and 1/2 means centered.  Default: 3/4

y_label_position
     Controls the position of both Y axis labels (titles). The value for
     this should be between 0 and 1, where 0 means aligned to the bottom, 1
     means aligned to the top, and 1/2 means centered.  Default: 1/2

x_labels_vertical
     If set to a true value, the X axis labels will be printed vertically.
     This can be handy in case these labels get very long.  Default: 0.

x_plot_values, y_plot_values
     If set to a true value, the values of the ticks on the x or y axes
     will be plotted next to the tick. Also see *x_label_skip,
     y_label_skip*.  Default: 1 for both.

box_axis
     Draw the axes as a box, if true.  Default: 1.

two_axes
     Use two separate axes for the first and second data set. The first
     data set will be set against the left axis, the second against the
     right axis. If this is set to a true value, trying to use anything
     else than 2 datasets will generate an error.  Default: 0.

zero_axis
     If set to a true value, the axis for y values of 0 will always be
     drawn. This might be useful in case your graph contains negative
     values, but you want it to be clear where the zero value is. (see also
     zero_axis_only and *box_axes*).  Default: 0.

zero_axis_only
     If set to a true value, the zero axis will be drawn (see zero_axis),
     and no axis at the bottom of the graph will be drawn.  The labels for
     X values will be placed on the zero exis.  Default: 0.

y_max_value, y_min_value
     Maximum and minimum value displayed on the y axis. If two_axes is a
     true value, then y1_min_value, y1_max_value (for the left axis), and
     y2_min_value, y2_max_value (for the right axis) take precedence over
     these.

     The range (y_min_value..y_max_value) has to include all the values of
     the data points, or *PNGgraph* will die with a message.

     For bar and area graphs, the range (y_min_value..y_max_value) has to
     include 0. If it doesn't, the values will be adapted before attempting
     to draw the graph.

     Default: Computed from data sets.

axis_space
     This space will be left blank between the axes and the text.
     Default: 4.

overwrite
     If set to 0, bars of different data sets will be drawn next to each
     other. If set to 1, they will be drawn in front of each other. If set
     to 2 they will be drawn on top of each other.  Default: 0.

     If you have negative values in your data sets, setting overwrite to 2
     might produce odd results. Of course, the graph itself would be quite
     meaningless, because overwrite = 2 is meant to show some cumulative
     effect.

Options for graphs with a numerical X axis
------------------------------------------

   First of all: PNGgraph does not support numerical x axis the way it
should. Data for X axes should be equally spaced. That understood: There
is some support to make the printing of graphs with numerical X axis
values a bit better, thanks to Scott Prahl. If the option x_tick_number is
set to a defined value, PNGgraph will attempt to treat the X data as
numerical.

   Extra options are:

x_tick_number
     If set to *'auto'*, PNGgraph will attempt to format the X axis in a
     nice way, based on the actual X values. If set to a number, that's the
     number of ticks you will get. If set to undef, PNGgraph will treat X
     data as labels.  Default: undef.

x_min_value, x_max_value
     The minimum and maximum value to use for the X axis.  Default:
     computed.

x_number_format
     See y_number_format

x_label_skip
     See y_label_skip

Options for graphs with bars
----------------------------

bar_spacing
     Number of pixels to leave open between bars. This works well in most
     cases, but on some platforms, a value of 1 will be rounded off to 0.
     Default: 0

Options for graphs with lines
-----------------------------

line_types
     Which line types to use for lines and *linespoints* graphs. This
     should be a reference to an array of numbers:

          $graph->set( line_types => [3, 2, 4] );

     Available line types are 1: solid, 2: dashed, 3: dotted, 4:
     dot-dashed.

     Default: [1] (always use solid)

line_type_scale
     Controls the length of the dashes in the line types. default: 6.

line_width
     The width of the line used in lines and *linespoints* graphs, in
     pixels.  Default: 1.

Options for graphs with points
------------------------------

markers
     This controls the order of markers in points and *linespoints*
     graphs.  This should be a reference to an array of numbers:

          $graph->set( markers => [3, 5, 6] );

     Available markers are: 1: filled square, 2: open square, 3: horizontal
     cross, 4: diagonal cross, 5: filled diamond, 6: open diamond, 7:
     filled circle, 8: open circle.

     Default: [1,2,3,4,5,6,7,8]

marker_size
     The size of the markers used in points and *linespoints* graphs, in
     pixels.  Default: 4.

Options for mixed graphs
------------------------

types
     A reference to an array with graph types, in the same order as the
     data sets. Possible values are:

          $graph->set( types => [qw(lines bars points area linespoints)] );
          $graph->set( types => ['lines', undef, undef, 'bars'] );

     values that are undefined or unknown will be set to default_type.

     Default: all set to default_type

default_type
     The type of graph to draw for data sets that either have no type set,
     or that have an unknown type set.

     Default: lines

Graph legends (axestype graphs only)
------------------------------------

   At the moment legend support is minimal.

   Methods

set_legend( *@legend_keys* );
     Sets the keys for the legend. The elements of @legend_keys correspond
     to the data sets as provided to plot() or *plot_to_png()*.

     If a key is undef or an empty string, the legend entry will be
     skipped.

set_legend_font( *font name* );
     Sets the font for the legend text (see also *set_title_font*).
     Default: GD::gdTinyFont.

   Options

legend_placement
     Where to put the legend. This should be a two letter key of the form:
     'B[LCR]|R[TCB]'. The first letter sipngies the placement (Bottom or
     Right), and the second letter signifies the alignment (Left, Right,
     Center, Top, or Bottom).  Default: 'BC'

     If the legend is placed at the bottom, some calculations will be made
     to ensure that there is some 'intelligent' wrapping going on. if the
     legend is placed at the right, all entries will be placed below each
     other.

legend_spacing
     The number of pixels to place around a legend item, and between a
     legend 'marker' and the text.  Default: 4

legend_marker_width, legend_marker_height
     The width and height of a legend 'marker' in pixels.  Defaults: 12, 8

lg_cols
     If you, for some reason, need to force the legend at the bottom to
     have a specific number of columns, you can use this.  Default:
     computed

Options for pie graphs
----------------------

  1. If set to a true value, the pie chart will be drawn with a 3d look.
     Default: 1.

  2. pie_height The thickness of the pie when 3d is true.  Default: 0.1 x
     PNG y size.

  3. start_angle The angle at which the first data slice will be
     displayed, with 0 degrees being "6 o'clock".  Default: 0.


NOTES
=====

   All references to colours in the options for this module have been
shortened to clr. The main reason for this was that I didn't want to
support two spellings for the same word ('colour' and 'color')

   Wherever a colour is required, a colour name should be used from the
package *Note PNGgraph/colour: PNGgraph/colour,.
`perldoc PNGgraph::colour' should give you the documentation for that
module, containing all valid colour names. I will probably change this to
read the systems rgb.txt file if it is available.

   Wherever a font name is required, a font from *Note GD: GD, should be
used.

AUTHOR
======

   Martien Verbruggen ported to GD 1.20+ (PNG) by Steve Bonds

Contact info
------------

   for PNGgraph questions: email: sbonds@agora.rdrop.com

   for GIFgraph questions: email: mgjv@comdyn.com.au

Copyright
---------

   Copyright (C) 1995-1998 Martien Verbruggen.  Copyright (C) 1999 Steve
Bonds.  All rights reserved.  This package is free software; you can
redistribute it and/or modify it under the same terms as Perl itself.


File: pm.info,  Node: PNGgraph/colour,  Next: POE,  Prev: PNGgraph,  Up: Module List

Colour manipulation routines for use with PNGgraph
**************************************************

NAME
====

   Colour - Colour manipulation routines for use with PNGgraph

SYNOPSIS
========

   use PNGgraph::colour qw( :colours :lists :files );

DESCRIPTION
===========

   The *Colour* Package provides a few routines to convert some colour
names to RGB values. Also included are some functions to calculate the hue
and luminance of the colours, mainly to be able to sort them.

   The :colours tags can be used to import the *_rgb*, *_hue*, and
*_luminance* functions, the :lists tag for *colour_list* and
*sorted_colour_list*, and the :files tag exports the *read_rgb* function.

FUNCTIONS
=========

Colour::colour_list( *number of colours* )
     Returns a list of *number of colours* colour names known to the
     package.

Colour::sorted_colour_list( *number of colours* )
     Returns a list of *number of colours* colour names known to the
     package, sorted by luminance or hue.  *NB.* Right now it always sorts
     by luminance. Will add an option in a later stage to decide sorting
     method at run time.

Colour::_rgb( *colour name* )
     Returns a list of the RGB values of *colour name*.

Colour::_hue( *R,G,B* )
     Returns the hue of the colour with the specified RGB values.

Colour::_luminance( *R,G,B* )
     Returns the luminance of the colour with the specified RGB values.

Colour::read_rgb( `file name' )
     Reads in colours from a rgb file as used by the X11 system.

     Doing something like:

          use PNGgraph::bars;
          use PNGgraph::colour;

          PNGgraph::colour::read_rgb("rgb.txt") or die "cannot read colours";

     Will allow you to use any colours defined in rgb.txt in your graph.

PREDEFINED COLOUR NAMES
=======================

   white, lgray, gray, dgray, black, lblue, blue, dblue, gold, lyellow,
yellow, dyellow, lgreen, green, dgreen, lred, red, dred, lpurple, purple,
dpurple, lorange, orange, pink, dpink, marine, cyan, lbrown, dbrown.


File: pm.info,  Node: POE,  Next: POE/Component,  Prev: PNGgraph/colour,  Up: Module List

event driven state machines
***************************

NAME
====

   POE - event driven state machines

SYNOPSIS
========

     #!/usr/bin/perl -w
     use strict;

     # Use POE!
     use POE;

     # Every machine is required to have a special state, _start, which
     # is used to the machine it has been successfully instantiated.
     # $_[KERNEL] is a reference to the process' global POE::Kernel
     # instance; $_[HEAP] is the session instance's local storage;
     # $_[SESSION] is a reference to the session instance itself.

     sub state_start {
       my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
       print "Session ", $session->ID, " has started.\n";
       $heap->{count} = 0;
       $kernel->yield('increment');
     }

     sub state_increment {
       my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
       print "Session ", $session->ID, " counted to ", ++$heap->{count}, ".\n";
       $kernel->yield('increment') if $heap->{count} < 10;
     }

     # The _stop state is special but not required.  POE uses it to tell
     # a session instance that it is about to be destroyed.  Stop states
     # contain last-minute resource cleanup, which often isn't necessary
     # since POE destroys $_[HEAP], and resource destruction cascades
     # down from there.

     sub state_stop {
       print "Session ", $_[SESSION]->ID, " has stopped.\n";
     }

     # Start ten instances of a session.  POE::Session constructors map
     # state names to the code that handles them.

     for (0..9) {
       POE::Session->create(
         inline_states =>
           { _start    => \&state_start,
             increment => \&state_increment,
             _stop     => \&state_stop,
           }
       );
     }

     # Start the kernel, which will run as long as there are sessions.

     $poe_kernel->run();
     exit;

DESCRIPTION
===========

   POE is an acronym of "Persistent Object Environment".  It originally
was designed as the core of a persistent object server where clients and
autonomous objects could interact in a sort of "agent space".  It was, in
this regard, very much like a MUD.  Evolution, however, seems to have
other plans.

   POE's heart is a framework for event driven state machines.  This heart
has two chambers: an event dispatcher and state machines that are driven
by dispatched events.  The modules are, respectively, POE::Kernel and
POE::Session.

   The remainder of POE consists of modules that help perform high-level
functions.  For example, POE::Wheel::ReadWrite encapsulates the logic for
select-based I/O.  Module dependencies always point towards lower level
code.  POE::Kernel and POE::Session, being at the lowest level, need none
of the others.  Since they are always required, they will be used whenever
POE itself is.

USING POE
=========

   Using POE modules can be pretty tedious.  Consider this example, which
pulls in the necessary modules for a line-based TCP server:

     use POE::Kernel;
     use POE::Session;
     use POE::Wheel::SocketFactory;
     use POE::Wheel::ReadWrite;
     use POE::Filter::Line;
     use POE::Driver::SysRW;

   Using POE directly optimizes this for laziness in two ways.  First, it
brings in POE::Kernel and POE::Session for you.  Second, subsequent
modules can be passed as parameters to the POE module without the "POE::"
prefix.

   The preceding example can then be written as:

     use POE qw( Wheel::SocketFactory Wheel::ReadWrite
                 Filter::Line Driver::SysRW
               );

WRITING POE PROGRAMS
====================

   Basic POE programs consist of four parts.

   * Preliminary program setup

     This is the usual overhead for writing a Perl program: a #! line,
     perhaps some use statements to import things, and maybe some global
     variables or configuration constants.  It's all pretty standard stuff.

          #!/usr/bin/perl -w
          use strict;
          use POE;

   * Define the program's states

     Here's where the code for each state is defined.  In a procedural
     program, it would be where subroutines are defined.  This part is
     optional in smaller programs, since states may be defined as inline
     anonymous coderefs when machines are instantiated.

          sub state_start {
            ...
          }

          sub state_increment {
            ...
          }

          sub state_stop {
            ...
          }

   * Instantiate initial machines

     POE's kernel stops when there are no more sessions to generate or
     receive transition events.  A corolary to this rule: The kernel won't
     even begin unless a session first has been created.  The SYNOPSIS
     example starts ten state machines to illustrate how POE may simulate
     threads through cooperative timeslicing.  In other words, several
     things may be run "concurrently" by taking a little care in their
     design.

          for (0..9) {
            POE::Session->create(
              inline_states =>
                { _start    => \&state_start,
                  increment => \&state_increment,
                  _stop     => \&state_stop,
                }
            );
          }

   * Start the kernel

     Almost nothing will happen until the event dispatcher starts.  A
     corolary to this rule: Nothing of much consequence will happen until
     the kernel is started.  As was previously mentioned, the kernel won't
     return until everything is finished.  This usually (but not
     necessarily) means the entire program is done, so it's common to exit
     or otherwise let the program end afterwards.

          $poe_kernel->run();
          exit;

POE's ARCHITECTURE
==================

   POE is built in distinct strata: Each layer requires the ones beneath
it but not the ones above it, allowing programs to use as much code as
they need but no more.  The layers are:

   * Events layer

     This was already discussed earlier.  It consists of an event
     dispatcher, POE::Kernel; POE::Session, which is a generic state
     machine; and POE::NFA, which is a non-deterministic finite automaton.

   * The "Wheels" I/O abstraction

     POE::Wheel is conceptually similar to a virus.  When one is
     instantiated, it injects its code into the host session.  The code
     consists of some unspecified states that perform a particular job.
     Unlike viruses, wheels remove their code when destroyed.

     POE comes with four wheels so far:

        * POE::Wheel::FollowTail

          FollowTail follows the tail of an ever-growing file.  It's
          useful for watching logs or pipes.

        * POE::Wheel::ListenAccept

          ListenAccept performs ye olde non-blocking socket listen and
          accept.  It's depreciated by SocketFactory, which does all that
          and more.

        * POE::Wheel::ReadWrite

          ReadWrite is the star of the POE::Wheel family.  It performs
          buffered I/O on unbuffered, non-blocking filehandles.  It almost
          acts like a Unix stream, only the line disciplines don't yet
          support push and pop.

          ReadWrite uses two other classes to do its dirty work: Driver and
          Filter.  Drivers do all the work, reading and/or writing from
          filehandles.  Filters do all the other work, translating
          serialized raw streams to and from logical data chunks.

          Drivers first:

             * POE::Driver::SysRW

               This is the only driver currently available.  It performs
               sysread and syswrite on behalf of Wheel::ReadWrite.  Other
               drivers, such as SendRecv, are possible, but so far there
               hasn't been a need for them.

          Filters next:

             * POE::Filter::Block

               This filter parses input as fixed-length blocks.  The
               output side merely passes data through unscathed.

             * POE::Filter::HTTPD

               This filter parses input as HTTP requests, translating them
               into HTTP::Request objects.  It accepts responses from the
               program as HTTP::Response objects, serializing them back
               into streamable HTTP responses.

             * POE::Filter::Line

               The Line filter parses incoming streams into lines and
               serializes outgoing lines into streams.  It's very basic.

             * POE::Filter::Reference

               The Reference filter is used for sending Perl structures
               between POE programs.  The sender provides references to
               structures, and Filter::Reference serializes them with
               Storable, FreezeThaw, or a serializer of your choice.  Data
               may optionally be compressed if Zlib is installed.

               The receiving side of this filter takes serialized data and
               thaws it back into perl data structures.  It returns a
               reference to the reconstituted data.

             * POE::Filter::Stream

               Filter::Stream does nothing of consequence.  It passes data
               through without any change.

        * POE::Wheel::SocketFactory

          SocketFactory creates sockets.  When creating connectionless
          sockets, such as UDP, it returns a fully formed socket right
          away.  For connecting sockets which may take some time to
          establish, it returns when a connection finally is made.
          Listening socket factories may return several sockets, one for
          each successfully accepted incoming connection.

POE COMPONENTS
==============

   A POE component consists of one or more state machines that
encapsulates a very high level procedure.  For example,
POE::Component::IRC (not included) performs nearly all the functions of a
fully featured IRC client.  This frees programmers from the tedium of
working directly with the protocol, instead letting them focus on what the
client will actually do.

   POE comes with only one core component, POE::Component::Server::TCP.
It is a thin wrapper around POE::Wheel::SocketFactory, providing the wheel
with some common default states.  This reduces the overhoad needed to
create TCP servers to its barest minimum.

   To-do: Publish a POE component SDK, which should amonut to little more
than some recommended design guidelines and MakeMaker templates for CPAN
publication.

Support Modules
===============

   Finally, there are some modules which aren't directly used but come
with POE.  These include POE::Preprocessor and the virtual base classes:
POE::Component, POE::Driver, POE::Filter and POE::Wheel.

   POE::Preprocessor is a macro processor.  POE::Kernel and POE::Session
use it to inline common code, making the modules faster and easier to
maintain.  There seem to be two drawbacks, however: Code is more difficult
to examine from the Perl debugger, and programs take a little longer to
start.  The compile-time penalty is negligible in the types of
long-running programs POE excels at, however.

   POE::Component exists merely to explain the POE::Component subclasses,
as do POE::Driver, POE::Filter and POE::Wheel.  Their manpages also
discuss options and methods which are common across all their subclasses.

ASCII ART
=========

   The ASCII art is gone.  If you want pretty pictures, contact the
author.  He's been looking for excuses to sit down with a graphics program.

OBJECT LAYER
============

   The object layer has fallen into disrepair again, and the author is
considering splitting it out as a separate Component.  If you've been
looking forward to it, let him know so he'll have an excuse to continue
with it.

SAMPLE PROGRAMS
===============

   The POE contains 28 sample programs as of this writing.  Please be
advised that some of them date from the early days of POE's development
and may not exhibit the best coding practices.

   The samples reside in the archive's ./samples directory.  The author is
considering moving them to a separate distribution to cut back on the
archive's size, but please contact him anyway if you'd like to see
something that isn't there.

Tutorials
---------

   POE's documentation is merely a reference.  It may not explain why
things happen or how to do things with POE.  The tutorial samples are
meant to compensate for this in some small ways.

   * tutorial-chat.perl

     This is the first and only tutorial to date.  It implements a simple
     chat server (not web chat) with rambling narrative comments.

Events Layer Examples
---------------------

   These examples started life as test programs, but the t/*.t type tests
are thousands of times terrificer.  Now the examples exist mainly as just
examples.

   * create.perl

     This program is essentially the same as sessions.perl, but it uses the
     newer POE::Session->create constructor rather than the original
     POE::Session->new one.

   * forkbomb.perl

     The "forkbomb" test doesn't really use fork, but it applies the
     fork-til-you-puke concept to POE's sessions.  Every session starts two
     more and exits.  It has a 200 session limit to keep it from eating
     resources forever.

   * names.perl

     The "names" test demonstrates two concepts: how to reference sessions
     by name, and how to communicate between sessions with an asynchronous
     ENQ/ACK protocol.

   * objmaps.perl

     This is a version of objsessions.perl that maps states to differently
     named object methods.

   * objsessions.perl

     This program is essentially the same as sessions.perl, but it uses
     object methods as states instead of inline coderefs.

   * packagesessions.perl

     This program is essentially the same as sessions.perl, but it uses
     package methods as states instead of inline coderefs.

   * queue.perl

     In this example, a single session is created to manage others beneath
     it.  The main session keeps a pool of children to perform asynchronous
     tasks.  Children stop as their tasks are completed, so the job queue
     controller spawns new ones to continue the work.  The pool size is
     limited to constrain the example's resource use.

   * selects.perl

     The "selects" example shows how to use POE's interface to select(2).
     It creates a simple chargen server and a client to visit it.  The
     client will disconnect after receiving a few lines from the server.
     The server will remain active until it receives SIGINT, and it will
     accept further socket connections.

   * sessions.perl

     This program is a basic example of Session construction, destruction
     and maintenance.  It's much more system friendly than forkbomb.perl.

   * signals.perl

     The "signals" example shows how sessions can watch for signals.  It
     creates two sessions that wait for signals and periodically post soft
     signals to themselves.  Soft signals avoid the underlying operating
     system, posting signal events directly through POE.  This also allows
     simulated and fictitious signals.

I/O Layer Examples
------------------

   These examples show how to use the Wheels abstraction.

   * fakelogin.perl

     The "fakelogin" example tests Wheels' ability to change the events
     they emit.  The port it listens on can be specified on the command
     line, and it listens on port 23 by default.

   * filterchange.perl

     This example tests POE::Wheel::ReadWrite's ability to change the
     filter it's using while it runs.

   * followtail.perl

     This program shows how to use POE::Wheel::FollowTail, a read-only
     wheel that follows the end of an ever-growing file.

     It creates 21 sessions: 10 that generate fictitious log files, 10 that
     follow the ends of these logs, and one timer loop to make sure none of
     the other 20 are blocking.  SIGINT will cause the program to clean up
     its /tmp files and stop.

   * httpd.perl

     This is a test of the nifty POE::Filter::HTTPD module.  The author can
     say it's nifty because he didn't write it.  The sample will try
     binding to port 80 of INADDR_ANY, but it can be given a new port on
     the command line.

   * proxy.perl

     This is a simple TCP port forwarder.

   * ref-type.perl

     The "ref-type" sample shows how POE::Filter::Reference can use
     specified serialization methods.  It's part of Philip Gwyn's work on
     POE::Component::IKC, an XML based RPC package.

   * refsender.perl and refserver.perl

     These samples use POE::Filter::Reference to pass copies of blessed and
     unblessed data between processes.  The standard Storable caveats (such
     as its inability to freeze and thaw coderefs) apply.

     refserver.perl should be run first, then refsender.  Check refserver's
     STDOUT to see what it received.

   * thrash.perl

     This is a harsh wheel test.  It sets up a simple TCP daytime server
     and a pool of clients within the same process.  The clients
     continually visit the server, creating and destroying several sockets
     a second.  The test will run faster (and thus be harsher on the
     system) if it is split into two processes.

   * udp.perl

     The "udp" sample shows how to create UDP sockets with IO::Socket and
     use them in POE.  It was a proof of concept for the SocketFactory
     wheel's UDP support.

   * watermarks.perl

     High and low watermarks are a recent addition to the ReadWrite wheel.
     This program revisits the author's good friend, the chargen server,
     this time implementing flow control.

     Seeing it in action requires a slow client.  Telnet or other raw TCP
     clients may work, especially if they are running at maximum niceness.

   * wheels.perl

     This program is a basic rot13 server.  It was used as an early test
     program for the whole Wheel abstraction's premise.

   * wheels2.perl

     The "wheels2" sample shows how to use separate input and output
     filehandles with a wheel.  It's a simple tcp socket client, piping
     betwene a socket and stdio.  Stdio is in cooked mode, with all its
     caveats.

Object Layer Examples
---------------------

   As was previously said, the object layer has fallen once again into
disrepair.  However, the olayer.perl sample program illustrates its
current state.

Proofs of Concepts
------------------

   These programs are prototypes for strange and wonderful concepts.  They
push POE's growth by stretching its capabilities to extrems and seeing
where it hurts.

   * preforkedserver.perl

     This example shows how to write pre-forking servers with POE.  It
     tends to dump core after a while, however, due signal issues in Perl,
     so it's not recommended as an example of a long running server.

     One work-around is to comment out the yield('_stop') calls (there are
     two).  These were added to cycle child servers.  The idea was borrowed
     from Apache, which only did this to thwart runaway children.  POE
     shouldn't leak memory, so churning the children shouldn't be needed.

     Still, it is a good test for one of POE's weaknesses.  This thorn in
     the author's side will remain enabled.

   * tk.perl

     The "tk" example is a prototype of POE's Tk support.  It sets up a Tk
     main window populated with some buttons and status displays.  The
     buttons and displays demonstrate FIFO, alarm and file events in the Tk
     environment.

COMPATIBILITY ISSUES
====================

   POE has tested favorably on as many Perl versions as the author can
find or harass people into trying.  This includes Linux, FreeBSD, OS/2 and
at least one unspecified version of Windows.  As far as I can tell, nobody
ever has tried it on any version of MacOS.

   POE has been tested with Perl versions as far back as 5.004_03 and as
recent as 5.6.0.  The CPAN testers are a wonderful bunch of people who
have dedicated resources to running new modules on a variety of platforms.
The latest POE tests are visible at
<http://testers.cpan.org/search?request=dist&dist=POE>.  Thanks, people!

   Please let the author know of breakage or success that hasn't been
covered already.  Thanks!

   Specific issues:

   * Various Unices

     No known problems.

   * OS/2

     No known problems.

   * Windows

     Windows support lapsed in version 0.0806 when I took out some code I
     wasn't sure was working.  Well, it was, and removing it broke POE on
     Windows.

     Douglas Couch reported that POE worked with the latest stable
     ActivePerl prior to version 5.6.0-RC1.  He said that RC1 supported
     fork and other Unix compatibilities, but it still seemed like beta
     level code.  I hope this changed with the release of 5.6.0-GA.

     Douglas writes:

          I've done some preliminary testing of the 0.0903 version and the
          re-addition of the Win32 support seems to be a success.  I'll do
          some more intensive testing in the next few days to make sure
          nothing else is broken that I haven't missed.

     And later:

          After testing out my own program and having no problems with the
          newest version (with Win32 support), I thought I'd test out some of
          the samples and relay my results.

          filterchange.perl and preforkedserver.perl both contain fork
          commands which are still unsupported by ActiveState's port of Perl,
          so they were both unsuccessful.  (this was anticipated for anything
          containing fork)

          ref-type.perl, refsender.perl, thrash.perl and wheels2.perl all ran
          up against the same unsupported POSIX macro.  According to the error
          message, my vendor's POSIX doesn't support the macro EINPROGRESS.

          [EINPROGRESS is fixed as of version 0.1003; see the Changes]

          Other than those particular problems all of the other sample scripts
          ran fine.

   * MacOS

     I have heard rumors from MacOS users that POE might work with MacPerl,
     but so far nobody has stepped forward with an actual status report.

SYSTEM REQUIREMENTS
===================

   * Recommendations

     POE would like to see certain functions, but it doesn't strictly
     require them.  For example, the sample programs use fork() in a few
     places, but POE doesn't require it to run.

     If Time::HiRes is present, POE will use it to achieve better accuracy
     in its select timeouts.  This makes alarms and delays more accurate,
     but POE is designed to work without it as well.

     POE includes no XS, and therefore it doesn't require a C compiler.  It
     should work wherever a sufficiently complete version of Perl does.

   * Hard Requirements

     POE requires Filter::Call::Util starting with version 0.1001.  This is
     part of the source filter package, Filter, version 1.18 or later.  The
     dependency is coded into Makefile.PL, and the CPAN shell can fetch and
     install this automatically for you.

     POE uses POSIX system calls and constants for portability.  There
     should be no problems using it on systems that have sufficient POSIX
     support.

     Some of POE's sample programs require a recent IO bundle, but you get
     that for free with recent versions of Perl.

   * Optional Requirements

     If you intend to use Filter::Reference, then you will need either the
     Storable or FreezeThaw module, or some other freeze/thaw package.
     Storable tends to be the fastest, and it's checked first.
     Filter::Reference can also use Compress::Zlib upon request, but it's
     not required.

     *If you intend to pass reference across machines, such as with Philip
     Gwyn's POE::Component::IKC, then be sure that both ends of the
     connection use the same version of the same libraries.  Subtle
     differences in libraries, or even between different versions of the
     same library, can cause mysterious errors when data is reconstituted
     on the receiving end.  When all else fails, upgrade to the latest
     version; this has been known to fix problems between Filter::Reference
     and Storable, for example.*

     Filter::HTTPD requires a small world of modules, including
     HTTP::Status; HTTP::Request; HTTP::Date and URI::URL.  The httpd.perl
     sample program uses Filter::HTTPD, which uses all that other stuff.

     The preforkedserver.perl sample program uses POE::Kernel::fork(),
     which in turn requires the fork() built-in function.  This may or may
     not be available on your planet.

     Other sample programs may require other modules, but the required
     modules aren't required if you don't require those specific modules.

SUPPORT RESOURCES
=================

   These are Internet resources where you may find more information about
POE.

   * The POE Mailing List

     POE has a mailing list at perl.org.  You may subscribe to it by
     sending e-mail:

          To: poe-help@perl.org
          Subject: (anything will do)

          Anything will do for the message body.

     All forms of feedback are welcome.

   * The POE Web Site

     POE has a web site where the latest development snapshot, along with
     the Changes file and other stuff may be found: <http://poe.perl.org/>

SEE ALSO
========

   This is a summary of POE's modules.

   * Events Layer

     POE::Kernel; POE::NFA; POE::Session

   * I/O Layer

     POE::Driver; POE::Driver::SysRW

     POE::Filter; POE::Filter::HTTPD; POE::Filter::Line;
     POE::Filter::Reference; POE::Filter::Stream

     POE::Wheel; POE::Wheel::FollowTail; POE::Wheel::ListenAccept;
     POE::Wheel::ReadWrite; POE::Wheel::SocketFactory

   * Object Layer

     These modules are in limbo at the moment.

     POE::Curator; POE::Object; POE::Repository; POE::Attribute::Array;
     POE::Runtime

   * Components

     POE::Component; POE::Component::Server::TCP

   * Supporting cast

     POE::Preprocessor

BUGS
====

   The Object Layer is still in early design, so it's not documented yet.

   There need to be more automated regression tests in the t/*.t
directory.  Please suggest tests; the author is short on ideas here.

   The documentation is in the process of another revision.  Here is a
progress report:

     POE                          rewritten 2000.05.15
     README                       rewritten 2000.05.16
     POE::Kernel                  rewritten 2000.05.19
     POE::Session                 rewritten 2000.05.21
     POE::Wheel                   rewritten 2000.05.22
     POE::Preprocessor            revised   2000.05.23

     POE::Component               queued
     POE::Component::Server::TCP  queued
     POE::Driver                  queued
     POE::Driver::SysRW           queued
     POE::Filter                  queued
     POE::Filter::Block           queued
     POE::Filter::HTTPD           queued
     POE::Filter::Line            queued
     POE::Filter::Reference       queued
     POE::Filter::Stream          queued
     POE::Wheel::FollowTail       queued
     POE::Wheel::ListenAccept     queued
     POE::Wheel::ReadWrite        queued
     POE::Wheel::SocketFactory    queued

AUTHORS & COPYRIGHT
===================

   POE is the combined effort of more people than I can remember
sometimes.  If I've forgotten someone, please let me know.

   * Addi

     Addi is <e-mail unknown>.

     Addi has tested POE and POE::Component::IRC on the Windows platform,
     finding bugs and testing fixes.  You'll see his name sprinkled
     throughout the Changes file.

   * Artur Bergman

     Artur Bergman is <artur@vogon-solutions.com>.

     Artur has contributed many hours and ideas.  He's also the author of
     Filter::HTTPD and Filter::Reference, as well as bits and pieces
     throughout POE.  His intangible contributions include feedback,
     testing, conceptual planning and inspiration.  POE would never have
     come this far without his support.

   * Douglas Couch

     Douglas Couch is <dscouch@purdue.edu>

     Douglas was the brave soul who stepped forward to offer valuable
     testing on the Windows platforms.  His reports helped get POE working
     on Win32 and are summarized earlier in this document.

   * Philip Gwyn

     Philip Gwyn is <gwynp@artware.qc.ca>.

     Philip extended the Wheels I/O abstraction to allow filters to be
     changed at runtime and provided patches to add the eminently cool
     Kernel and Session IDs.  He also enhanced Filter::Reference to support
     different serialization methods.  His intangible contributions include
     the discovery and/or destruction of several bugs (see the Changes
     file) and a thorough code review around version 0.06.

   * Dave Paris

     Dave Paris is <dparis@w3works.com>.  He often goes by the nickname
     "a-mused".

     Dave tested and benchmarked POE around version 0.05, discovering some
     subtle (and not so subtle) timing problems.  The pre-forking server
     was his idea.  Versions 0.06 and later should scale to higher loads
     because of his work.  His intangible contributions include lots of
     testing and feedback, some of which is visible in the Changes file.

   * Dieter Pearcey is <dieter@bullfrog.perlhacker.org>.  He goes by
     several Japanese nicknames.

     Dieter patched Wheel::FollowTail to be more useful and has contributed
     the basic Filter::Block, along with documentation!

   * Robert Seifer

     Robert Seifer is <e-mail unknown>.  He rotates IRC nicknames
     regularly.

     Robert contributed entirely too much time, both his own and his
     computers, towards the detection and eradication of a memory
     corruption bug that POE tickled in earlier Perl versions.  In the end,
     his work produced a simple compile-time hack that worked around a
     problem relating to anonymous subs, scope and @{} processing.

   * Dennis Taylor

     Dennis Taylor is <dennis@funkplanet.com>.  Dennis has been testing,
     debugging and patching bits here and there, such as Filter::Line which
     he improved by leaps in 0.1102.  He's also the author of
     POE::Component::IRC, which isn't included here but may be found at
     either <http://www.infobot.org/dev/POE/> or
     <http://www.funkplanet.com/POE/>.

   * Others?

     Anyone who has been forgotten, please contact the author.

Author
------

   * Rocco Caputo

     Rocco Caputo is <troc+poe@netrus.net>.  POE is his brainchild.

     Except where otherwise noted, POE is Copyright 1998-2000 Rocco Caputo.
     All rights reserved.  POE is free software; you may redistribute it
     and/or modify it under the same terms as Perl itself.

   Thank you for reading!


File: pm.info,  Node: POE/Component,  Next: POE/Component/IRC,  Prev: POE,  Up: Module List

POE Stand-Alone Sessions
************************

NAME
====

   POE::Component - POE Stand-Alone Sessions

SYNOPSIS
========

   Varies from component to component.

DESCRIPTION
===========

   POE components are sessions that have been designed as stand-alone
modules.  They tend to be interfaced through POE::Kernel::post() or
call(), but this is not a formal convention.

   The POE::Component namespace was started to provide a place for others
publish their POE modules without requiring coordination with the main POE
distribution.

BUGS
====

   The POE::Component namespace should probably be coordinated, but who
has time for that?

AUTHORS & COPYRIGHTS
====================

   Please see the POE manpage or manpages for specific components.


