# Event - phpMan

## NAME
    Event - Event loop processing

## SYNOPSIS
     use Event qw(loop unloop);

     # initialize application
     Event->flavor(attribute => value, ...);

     my $ret = loop();

     # and some callback will call
     unloop('ok');

## DESCRIPTION
    ALERT: Marc Lehmann may have taken over the future of event loops in
    Perl. Check out his libev library and EV Perl module. 25 Aug 2009

    The Event module provide a central facility to watch for various types
    of events and invoke a callback when these events occur. The idea is to
    delay the handling of events so that they may be dispatched in priority
    order when it is safe for callbacks to execute.

    Events (in the ordinary sense of the word) are detected by watchers,
    which reify them as events (in the special Event module sense). For
    clarity, the former type of events may be called "source events", and
    the latter "target events". Source events, such as signals arriving,
    happen whether or not they are being watched. If a source event occurs
    which a watcher is actively watching then the watcher generates a
    corresponding target event. Target events are only created by watchers.
    If several watchers are interested in the same source event then each
    will generate their own target event. Hence, any particular source event
    may result in zero, one, two, or any number of target events: the same
    as the number of watchers which were actively watching for it.

    Target events are queued to be processed in priority order (priority
    being determined by the creating watcher) and in FIFO order among events
    of the same priority. Queued ("pending") events can, in some cases, be
    cancelled before being processed. A queued event is processed by being
    passed to the callback function (or method on a particular object or
    class) which was specified to the watcher.

    A watcher, once created, operates autonomously without the Event user
    having to retain any reference to it. However, keeping a reference makes
    it possible to modify most of the watcher's characteristics. A watcher
    can be switched between active and inactive states. When inactive, it
    does not generate target events.

    Some types of source event are not reified as target events immediately.
    Signals received, for example, are counted initially. The counted
    signals are reified at certain execution points. Hence, signal events
    may be processed out of order, and if handled carelessly, on the wrong
    side of a state change in event handling. A useful way to view this is
    that occurrence of the source event is not actually the arrival of the
    signal but is triggered by the counting of the signal.

    Reification can be forced when necessary. The schedule on which some
    other events are created is non-obvious. This is especially the case
    with watchers that watch for a condition rather than an event. In some
    cases, target events are generated on a schedule that depends on the
    operation of the event loop.

## PERL API
    Events (the occurrence of such) are noticed and queued by 'event
    watchers'. The creation and configuration of event watchers is the
    primary topic of the rest of this document.

    The following functions control or interrogate the event loop as a
    whole:

    $result = loop([$timeout])
        Will enter a loop that calls one_event() until unloop() is called.
        The argument passed to unloop() is the return value of loop(). Loops
        can be nested.

    unloop($result)
        Make the inner-most loop() return with $result.

    unloop_all($result)
        Cause all pending loop()s to return immediately. This is not
        implemented with "die". It is works as if "unloop($result)" were
        called for all nested loops.

    sweep([$max_prio])
        Queue all pending events and dispatch any with priority strictly
        less than $max_prio (the highest priority is 0). The default is to
        process all events except idle events. (While idle events are
        ignored by sweep, idle watchers are not ignored. If you want to
        avoid triggering an idle watcher then set "max" to "undef" or
        "stop()" it.)

    one_event([$timeout])
        If any events are outstanding then invoke the corresponding callback
        of the highest priority event. If there are no events available,
        block forever or until $timeout. Use of this API is not recommended
        because it is not efficient and does not trap exceptions. However,
        you might wish to understand how it works:

        1   Queue asyncronous events (signals, etc). That is, previously
            recorded events are reified.

        2   If there are any events with priority 5 or less (see StarvePrio)
            then service the next one and return.

        3   Calculate the maximum wait time (minimum time till the next
            timer expiration) and pass control to the poll/select system
            call. Upon return, queue all pending events.

        4   Queue asyncronous events again.

        5   If there are any events then service the next one and return.

        6   Service the next idle watcher.

        StarvePrio is the priority level for which events are dispatched
        during step 2. It cannot be changed without a recompile. In the rare
        case that an event is always pending at step 2 then I/O watchers
        will starve. However, this is highly unlikely since async watchers
        should never queue events so rapidly.

    all_watchers()
        Returns a list of all watchers (including stopped watchers).

    all_running()
        Returns a list of all watchers with actively running callbacks.
        Watchers are returned in order of most recent to least recent.

    all_idle()
        Returns a list of all the idle watchers. If the event queue is very
        busy, all the idle watchers will sit on the idle queue waiting to
        run. However, be aware that if an idle watcher has the "max"
        attribute set then it will queue a normal event when its "max" wait
        time is exceeded.

    queue_pending()
        Examines asynchronous source events (timers & signals) and reifies
        them as target events. "queue_pending()" is only called implicitly
        by "sweep()" and "one_event()". Otherwise, "queue_pending()" is not
        called implicitly.

        NOTE: Signal watchers generate target events according to which
        watchers are active at the time that "queue_pending()" is called
        rather than according to the time the signal is received. This is
        best explained by example. See the file "demo/queue_pending.t".

  Event Watcher Constructors
    All watchers are constructed in one of the following ways:

      $w = Event->flavor( [attr1 => $value,]... );

      $w = [Event::flavor]($Class, [attr1 => $value,]...);

      $w = [Event::flavor]->new([attr1 => $value,]...);

    Where *flavor* is substituted with the kind of watcher. Built-in types
    include idle, io, signal, timer, and var.

    New watchers (hopefully) have reasonable defaults and can also be
    customized by passing extra attributes to the constructor. When created,
    watcher objects are "started" and are waiting for events (see
    "$event->start" below).

    [NetServer::Portal] can display watchers in real-time, formatted similarly
    to the popular "top" program. You may find this a useful aide for
    debugging.

  Shared Watcher Attributes
    Watchers are configured with attributes (also known as properties). For
    example:

       $watcher->cb(\&some_code);   # set callback

       warn $event->w->desc.": ".$event->hits." events happened; Wow!";

    All watchers support the following attributes: cb, cbtime, debug, desc,
    prio, max_cb_tm, reentrant, and repeat. Watcher constructors accept the
    preceding and additionally: async and nice. Moreover, watchers also
    offer extra attributes according to their specialty.

  Shared Watcher Methods
    The following methods are available for all watchers:

    $watcher->start
        Activate the watcher. Watchers refuse to "start()" without
        sufficient configuration information to generate events.
        Constructors always invoke "start()" unless the "parked=>1" option
        is requested. You will need to set the parked option if you
        preallocate unconfigured watchers.

        Note: If there are any unreified asynchronous events that are of
        interest to the watcher, it will see these events even though they
        happened before it was started. This affects signal watchers, but
        there will only be existing unreified signal events if Event was
        already handling the signal, which it would only do if there were
        another active watcher for the same signal. If this situation might
        occur, and it would be a problem for the new watcher to see older
        events, call "queue_pending()" immediately before starting the new
        watcher in order to reify any outstanding events. This explanation
        may be more clear if read along with "demo/queue_pending.t".

    $watcher->again
        This is the same as the "start" except if a watcher has special
        repeat behavior. For example, repeating timers recalculate their
        alarm time using the "interval" parameter.

    $watcher->now
        Cause the watcher to generate an event, even if it is stopped. The
        callback may or may not run immediately depending upon the event's
        priority. If you must unconditionally invoke the callback, consider
        something like

          $w->cb->($w);

    $watcher->stop
        Don't look for events any more. Running events are allowed to
        complete but pending events are cancelled. Note that a stopped
        watcher can be reactivated by calling the "start" or "again"
        methods.

        Watchers are stopped implicitly if their new configuration deprives
        them of the ability to generate events. For instance:

          my $io_watcher = Event->io(timeout => 1);  # started
          $io_watcher->timeout(undef);               # stopped implicitly
          $io_watcher->[timeout(1)];                   # still stopped
          $io_watcher->start;                        # restarted

    $watcher->cancel
        Stop and destroy $watcher. Running events are allowed to complete
        but pending events are cancelled. Cancelled watchers are no longer
        valid except for read-only operations. For example, prio() can
        return the watcher's priority, but start() will fail.

    $watcher->is_cancelled
        Reports whether the $watcher has been cancelled.

    $watcher->is_active
        Reports whether the $watcher has been started. The return value is
        not affected by suspend.

    $watcher->is_running
        Zero if the callback is not running. Otherwise, the number of levels
        that the callback has been entered. This can be greater than one if
        a "reentrant" callback invokes "loop" (or "sweep", with lesser
        probability).

    $watcher->is_suspended
        Reports whether the $watcher is suspended. Suspension is a debugging
        feature; see the discussion of the "suspend" attribute below.

    $watcher->pending
        In scalar context, returns a boolean indicating whether this watcher
        has any events pending in the event queue. In array context, returns
        a list of all the watcher's pending events.

        Note that this does not check for unreified asynchronous events.
        Call "queue_pending()" first if you want to see signals received
        since the last operation of the event loop.

  Watcher Types
    idle
        Extra attributes: min => $seconds, max => $seconds

        Watches for the Event system to be idle, i.e., to have no events
        pending. If the system is never idle, an event will be generated at
        least every "max" seconds. While Event is idle, events will be
        generated not more often than "min" seconds.

        If neither "min" nor "max" is specified, the watcher defaults to
        one-shot behaviour ("repeat" false), otherwise it defaults to
        repeating. In either case, the default can be overridden by
        specifying a "repeat" attribute. "min" defaults to 0.01, and "max"
        defaults to infinity.

    var Extra attributes: var => \$var, poll => 'rw'

        Var watchers generate events when the given variable is read from or
        written to, as specified by "poll". "poll" defaults to "w".

        As perl is a concise language, it is often difficult to predict when
        a variable will be read. For this reason, variable watchers should
        poll only for writes unless you know what you are doing.

    timer
        Extra attributes: at => $time, after => $sec, interval => $sec, hard
        => $bool

        Generate events at particular times. The $time and $sec are in
        seconds. Fractional seconds may be used if [Time::HiRes] is available.
        "at" and "after" are mutually exclusive.

        "at" or "after" specify the initial time that the event will
        trigger. Subsequent timer events occur at intervals specified by
        "interval" or "after" (in that order of preference) if either was
        supplied. The timer defaults to one-shot behaviour if "interval" was
        not specified, or repeating behaviour if "interval" was specified;
        in either case this can be overridden by providing "repeat"
        explicitly.

        You need to know the time at the start of today if you are trying to
        set timers to trigger at day relative times. You can find it with:

          use [Time::Local];
          my $TodaySeconds = int timelocal(0,0,0,(localtime)[3,4,5]);

        This calculation may seem a little heavy weight. If you want to use
        UTC rather than local time then you can use this instead:

          my $TodaySeconds = time - time % 86400;

        Beware that, due to lags in the event loop, the "interval" timeout
        may already be in the past. If the "hard" flag is set, the event
        will be queued for execution relative to the last time the callback
        was invoked. However, if "hard" is false the new timeout will be
        calculated relative to the current time. "hard" defaults to false.

    io  Extra attributes: fd => $fd, poll => 'rwe' [timeout => $seconds,
        hard => $bool, timeout_cb => \&code]

        The callback is invoked when the file descriptor, "fd", has data to
        be read, written, or pending exceptions. "fd" can be a GLOB, an
        [IO::Handle] object, or a file number (file descriptor). "poll"
        defaults to "r".

        Note that it is your option whether to have multiple watchers per
        file handle or to use a single watcher for all event conditions.

        If "timeout" is set, events are also generated regularly if no
        actual I/O event occurs. If "timeout_cb" is set then timeouts use
        this alternate callback instead of the main callback.

    signal
        Extra attribute: signal => $str

        Generates events based on signal arrival. The events are not
        actually generated immediately when the signal arrives: signals
        received are counted and reified by "queue_pending()" or implicitly
        by "one_event()". Several signals of the same type may be merged
        into a single event. In such cases, the number of signals
        represented by a single event is stored in the "hits" attribute.

  PRIORITY
    Priority is used to sort the event queue. Meaningful priorities range
    from -1 to 6 inclusive. Lower numbers mean higher priority (-1 is the
    highest priority and 6 is the lowest). If multiple events get queued,
    the ones with the highest priority are serviced first. Events with equal
    priority are serviced in first-in-first-out order.

      use Event qw(PRIO_HIGH PRIO_NORMAL);   # some constants

      LEVELS: -1      0      1      2      3      4      5      6
              ----------------------+-------------+---------------
                                PRIO_HIGH     PRIO_NORMAL

    A negative priority causes the callback to be invoked immediately upon
    event occurrence. Use this with caution. While it may seem advantageous
    to use negative priorities, they bypass the whole point of having an
    event queue.

    Each watcher has a *default priority*, assigned by its constructor:

      io       PRIO_NORMAL
      signal   PRIO_HIGH
      timer    PRIO_NORMAL
      var      PRIO_NORMAL

    Default priorities are stored in ${"Event::${type}::DefaultPriority"}.
    If the default priority is not satisfactory for your purposes, the
    constructor options "nice", "async", or "prio" can be used to adjust it.
    "nice" specifies an offset from the default priority; "async" forces the
    priority to -1; and "prio" assigns a given priority of your choice. If
    more than one of these options are given then "prio" overrides "async"
    overrides "nice".

  WATCHER CONSTRUCTOR ATTRIBUTES
    These options are only supported as constructor arguments.

    after => $seconds
        See the discussion of the timer watcher.

    async => $bool
        If $bool then the watcher priority is set to -1.

    nice => $offset
        Offset from the default priority.

    parked => $yes
        By default, watcher constructors automatically invoke the "start()"
        method. If you don't want the watcher started then request
        "parked=>1".

  WATCHER ATTRIBUTES
    at => $time
        The expiration time in the same units as the system clock. For a
        timer, "at" will usually be in the future.

    cb => \&code
    cb => [$class_or_object, $method_name]
        The function or method to call when an event is dispatched. The
        callback is invoked with $event as its only argument.

        Perhaps you are wondering what happens if something goes wrong and
        an untrapped "die" occurs within your callback? $[Event::DIED] is just
        for this purpose. See the full description of "DIED" below.

    cbtime => $time
        When the callback was invoked most recently.

    data => $anything
        The "data()" method associates arbitrary data with a watcher.

        This method is not intended for implementers of watchers. If you are
        subclassing or implementing a watcher, consider the "private()"
        method.

    debug => $bool
        Debugging can be activated globally or per watcher. When debugging
        is enabled for a particular watcher, $[Event::DebugLevel] is treated
        as two levels higher. Levels of 1, 2, 3, or 4 give progressively
        more diagnostics on STDERR.

    desc => $string
        An identifying name. If this is not passed explicitly to the
        constructor, it will be initialized with a string that attempts to
        identify the location in the source code where the watcher was
        constructed.

    fd => $filehandle
        This attribute can accept either a perl-esque filehandle or a system
        call derived file descriptor number.

    hard => $bool
        Determines how repeating timers (or timeouts) are recalculated. The
        timer is restarted either before or after the callback depending on
        whether it is true or false, respectively. In long-running callbacks
        this can make a significant difference.

    interval => $seconds
        How long between repeating timeouts. The "at" attribute is
        recalculated using "interval" upon callback return.

    max => $seconds
        The maximum number of seconds to wait before triggering the
        callback. Similar to a "timeout".

    max_cb_tm => $seconds
        The maximum number of seconds to spend in a callback. If a callback
        uses more time then it is aborted. Defaults to 1 sec. This feature
        is normally disabled. See [Event::Stats].

    min => $seconds
        Enforce a minimum number of seconds between triggering events.

    poll => $bits
        Determines which kinds of events are of interest. This attribute can
        be set with either strings or bit constants. The bit constants are
        available via 'use [Event::Watcher] qw(R W E T);'.

          string constant description
          ------ -------- ---------------
           'r'     R      read
           'w'     W      write
           'e'     E      exception
           't'     T      timeout

        Thus, both of these statements enable interest in read:

          $w->poll($w->poll . 'r');
          $w->poll($w->poll | R);

        A given type of watcher may support all or a subset of the available
        events.

    prio => $level
        Changes the watcher's priority to the given level. Events generated
        by a watcher usually inherit the priority of the watcher.

    private => $anything
        Use the "private()" method to associate arbitrary data with a
        watcher. This method is intended for implementers of watchers or
        watcher subclasses. Each caller's package accesses its own private
        attribute.

    reentrant => $bool
        By default, callbacks are allowed to invoke "sweep" or "loop" which
        in turn may invoke the same callback again recursively. This can be
        useful but can also be confusing. Moreover, if you keep reentering
        callbacks you will quickly run out of stack space. Disable this
        feature per watcher by setting reentrant to false. This will cause
        the watcher to be suspended during recursive calls to "sweep" or
        "loop".

    repeat => $bool
        The repeat flag controls whether the callback should either be
        one-shot or continue waiting for new events. The default setting
        depends on the type of watcher. *io*, *signal*, and *var* default to
        true.

    signal => $str
        The callback is invoked after the specified signal is received. The
        $str string should be something like 'INT' or 'QUIT'. Also see the
        documentation for %SIG.

        A given signal can be handled by %SIG or Event, but not both at the
        same time. Event handles the signal as long as there is at least one
        active watcher. If all watchers for the signal are cancelled or
        stopped then Event sets the signal handler to SIG_DFL.

    suspend => $bool
        Stop looking for events. Running events are allowed to complete, but
        queued events are cancelled.

        Suspend is for debugging. If you suspend all watchers in an
        application then you can examine the complete state unchanged for as
        long as you like without worrying about timer expirations. If you
        actually wish to stop a watcher then use the "stop()" method.

    timeout => $seconds
        The number of seconds before a watcher times out.

    timeout_cb => \&code
    timeout_cb => [$class_or_object, $method_name]
        This is an optional attribute for use when it is desired that
        timeouts be serviced in a separate code path than normal events.
        When this attribute is unset, timeouts are serviced by "cb".

    var => $ref
        A reference to the variable being watched.

  EVENT ATTRIBUTES
    got => $bits
        "got" is available in the callback of watchers with "poll". "got" is
        in the same format as "poll" except that it gives what kind of event
        actually happened. In contrast, "poll" is just an indication of
        interest.

    hits => $int
        Signals in quick succession can be clumped into a single event. The
        number of signals clumped together is indicated by this attribute.
        This is always one for event types which don't clump.

    prio => $level
        Be aware that this priority can differ from the watcher's priority.
        For instance, the watcher's priority may have changed since the
        event was generated. Moreover, the C extension API offers the
        freedom to queue events of arbitrary priority.

    w => $watcher
        This method return the event's watcher. It is read-only.

  Customization and Exceptions
    *   $[Event::DebugLevel]

        Enables progressively more debugging output. Meaningful levels range
        from 1 (least output) to 5 (most output). Also see "debug".

    *   $[Event::DIED]

        When "loop" or "sweep" is called, an exception context is
        established for the duration of event processing. If an exception is
        detected then $[Event::DIED] is invoked. The default hook uses "warn"
        to output the exception. After the DIED handler completes, event
        processing continues as if nothing happened.

        If you'd like more detailed output you can install the verbose
        handler:

          $[Event::DIED] = \&[Event::verbose_exception_handler];

        Or you can write your own. The handler is invoked like this:

          $[Event::DIED]->($event, $@);

        If you do not want to continue looping after an error, you can do
        something like this:

          $[Event::DIED] = sub {
            [Event::verbose_exception_handler](@_);
            [Event::unloop_all]();
          };

    *   Event->add_hooks(key => sub { ... }, ...);

        The bulk of Event's implementation is in C for maximum performance.
        The "add_hooks" method allows insertion of perl code at key points
        in the optimized event processing core. While flexible, this can
        hurt performance *significantly*. If you want customization *and*
        performance, please see the C API.

        Currently support hooks are detailed as follows:

          hook          purpose
          ------------- ----------------------------------------------
          prepare       returns minimum time to block (timeable)
          check         assess state after normal return from select/poll
          asynccheck    check for signals, etc
          callback      invoked before each event callback

## C API
    Event also has a direct API for callbacks written exclusively in C. See
    [Event::MakeMaker].

WHAT ABOUT THREADS?
    Event loops and threads are two different solutions to the same problem:
    asynchronous processing. Event loops have been around since the
    beginning of computing. They are well understood and proven to be a good
    solution for many applications.

    While event loops make use of basic operating system services, the bulk
    of their implementation is usually outside the kernel. While an event
    loop may appear to do many things in parallel, it does not, even on
    multiprocessor hardware. Actions are always dispatched sequentially.
    This implies that long running callbacks must be avoided because
    otherwise event processing is halted.

    Event loops work well when actions are short and to the point.
    Long-running tasks must be broken into short steps and scheduled for
    execution. Some sort of a state machine is usually required. While a
    big, complex application server is usually simpler to implement in a
    multithreaded fashion, a web browser can easily get by without threads.
    Consider a JPEG file download and render. When some new bytes are
    available they are sorted to the right place on the screen. Only a
    little state must be kept to keep track of how much has been rendered
    and to process subsequent incoming bytes.

    Threads can either substitute for an event loop or complement it.
    Threads are similar to processes in that the operating system manages
    task switching for you. However, the difference is that all threads
    share the same address space. This is good and bad. Higher performance
    can be achieved but since data is shared between threads, extreme care
    must be taken to access or modify global data. The operating system can
    switch threads at any moment or can execute multiple threads
    simultaneously. I hope this sounds dangerous! It is! Threads can
    introduce maddeningly complicated and hard to debug synchronization
    problems.

    Threads are like rocket fuel. They are essential when you really need
    them but most applications would be better off with a simple event loop.
    Even if threads are genuinely needed, consider confining them to the
    parts of an application where truly scalable performance is really worth
    the difficulty of a multithreaded implementation. For example, most GUIs
    applications do not need threads and most scientific compute intensive
    problems can be isolated from event dispatching. On the other hand, high
    performance transaction servers generally do mandate a truly
    multithreaded approach.

    Another consideration is that threads are not quite as widely available
    as event loops. While a few forward-thinking operating systems have
    offered threads since the beginning, their addition to many popular
    operating systems is much more recent and some still offer no threads
    support. If portability is a requirement, one must check that threads
    support is available and also carefully test a particular threads
    implementation to see whether it supports the features you need. It is
    likely that all platforms will have a solid implementation soon but at
    this point in history it is best to double check.

    Many suggestions by Mark Mielke <<Mark.Mielke.markm@nt.com>>

WHAT ABOUT NON-PREEMPTIVE THREADS?
    The Java language is oriented to use non-preemptive threads, yet even
    Java uses an event-loop for Swing (AFAIK). That is one of the reasons I
    don't use Java for network-centric applications. My belief is that the
    benefit of multi-threading is the gain in performance on SMP hardware.
    In my view, non-preemptive threads (java green-threads) are usually poor
    design. I find them harder to work with, harder to debug, and slower for
    a rather marginal gain in readability. I really like working with a
    state machine. I find it leads to more stable and better code. It also
    has the benefit of abstracting away how concurrency is achieved.

    Contributed by <artur@vogon-solutions.com>, 12 Jul 1999.

## BUGS
    No support for epoll, or better, libevent.

    The scope of events is pretty strange compared to most other perl
    objects. I'm not sure if this is a bug or a feature (OK, probably it was
    a mistake). We'll probably want to re-work things for Perl6.

    The meaning of $io->[timeout(0)] might change. Use "undef" to unset the
    timeout.

    There seems to be some sort of bug in the global destruction phase:

      Attempt to free unreferenced scalar during global destruction.
      Use of uninitialized value during global destruction.
      Explicit blessing to '' (assuming package main) during global
      destruction.

## THE FUTURE
    Even if this module does not end up being the One and True Event Loop,
    the author will insure that it is source compatible with its successor,
    or arrange for gradual migration. Back in the early days, the Event
    programming API was changing at every release. Care was taken to allow
    the old API to continue to work, and the transition was eased by
    printing out lots of warnings about the new usage. So you shouldn't sit
    on your hands in anticipation of the One and True Event Loop. Just start
    coding!

## ALSO SEE
    *   Useful and Fun

        [Time::HiRes], [NetServer::Portal], [Time::Warp]

    *   Message Passing

        COPE, [IPC::LDT], Event-tcp

    *   GUI

        While Tk does not yet support Event, PerlQt does.

    *   C API

        Inline

## SUPPORT
    If you have insights or complaints then please subscribe to the mailing
    list! Send email to:

      <perl-loop-subscribe@perl.org>

## AUTHOR
    Joshua N. Pritikin <<jpritikin@pobox.com>>

## ACKNOWLEDGMENT
    Initial 0.01 implementation by Graham Barr <<gbarr@pobox.com>>. Other
    contributors include at least those lists below and folks mentioned in
    the ChangeLog.

     Gisle Aas <<gisle@aas.no>>
     Uri Guttman <<uri@sysarch.com>>
     Nick Ing-Simmons <<nick@ni-s.u-net.com>> (Tk)
     Sarathy <<gsar@engin.umich.edu>>
     Jochen Stenzel <<perl@jochen-stenzel.de>>

## COPYRIGHT
    Copyright © 1997 Joshua Nathaniel Pritikin & Graham Barr

    Copyright © 1998, 1999, 2000, 2001, 2002, 2003, 2004 Joshua Nathaniel
    Pritikin

    All rights reserved. This program is free software; you can redistribute
    it and/or modify it under the same terms as Perl itself.

