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


File: pm.info,  Node: CPAN/Admin,  Next: CPAN/Checksums,  Prev: CPAN,  Up: Module List

A CPAN Shell for CPAN admins
****************************

NAME
====

   CPAN::Admin - A CPAN Shell for CPAN admins

SYNOPSIS
========

   perl -MCPAN::Admin -e shell

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

   CPAN::Admin is a subclass of CPAN that adds the commands register and
`modsearch' to the CPAN shell.

   register calls get on the named module, assembles a couple of
informations (description, language), and calls Netscape with the -remote
argument so that a form is filled with all the assembled informations and
the registration can be performed with a single click. If the command line
has more than one argument, register does not run a get, instead it
interprets the rest of the line as DSLI status, description, and userid
and sends them to netscape such that the form is again mostly filled and
can be edited or confirmed with a single click. CPAN::Admin never performs
the submission click for you, it is only intended to fill in the form on
PAUSE and leave the confirmation to you.

   `modsearch' simply passes the arguments to the search engine for the
modules@perl.org mailing list at http://www.xray.mpe.mpg.de where all
registration requests are stored. It does so in the same way as register,
namely with the `netscape -remote' command.

   An experimental feature has also been added, namely to color already
registered modules in listings. If you have Term::ANSIColor installed, the
u, r, and m commands will show already registered modules in green.

PREREQISITES
============

   URI::Escape, netscape browser available in the path, netscape must
understand the -remote switch (as far as I know, this is only available on
UNIX); coloring of registered modules is only available if Term::ANSIColor
is installed.


File: pm.info,  Node: CPAN/Checksums,  Next: CPAN/FirstTime,  Prev: CPAN/Admin,  Up: Module List

Write a CHECKSUMS file for a directory as on CPAN
*************************************************

NAME
====

   CPAN::Checksums - Write a CHECKSUMS file for a directory as on CPAN

SYNOPSIS
========

     use CPAN::Checksums qw(updatedir);
     my $success = updatedir($directory);

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

   updatedir takes a directory name as argument and writes a CHECKSUMS
file in that directory unless a previously written CHECKSUMS file is there
that is still valid. Returns 2 if a new CHECKSUMS file has been written, 1
if a valid CHECKSUMS file is already there, otherwise dies.

   Setting the global variable $CAUTION causes updatedir to report changes
of files in the attributes size, mtime, md5, or `md5-ungz' to STDERR.

AUTHOR
======

   Andreas Koenig, andreas.koenig@anima.de

SEE ALSO
========

   perl(1).


File: pm.info,  Node: CPAN/FirstTime,  Next: CPAN/Nox,  Prev: CPAN/Checksums,  Up: Module List

Utility for CPAN::Config file Initialization
********************************************

NAME
====

   CPAN::FirstTime - Utility for CPAN::Config file Initialization

SYNOPSIS
========

   CPAN::FirstTime::init()

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

   The init routine asks a few questions and writes a CPAN::Config file.
Nothing special.


File: pm.info,  Node: CPAN/Nox,  Next: CPAN/Site,  Prev: CPAN/FirstTime,  Up: Module List

Wrapper around CPAN.pm without using any XS module
**************************************************

NAME
====

   CPAN::Nox - Wrapper around CPAN.pm without using any XS module

SYNOPSIS
========

   Interactive mode:

     perl -MCPAN::Nox -e shell;

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

   This package has the same functionality as CPAN.pm, but tries to
prevent the usage of compiled extensions during it's own execution. It's
primary purpose is a rescue in case you upgraded perl and broke binary
compatibility somehow.

SEE ALSO
========

   CPAN(3)


File: pm.info,  Node: CPAN/Site,  Next: CPAN/WAIT,  Prev: CPAN/Nox,  Up: Module List

CPAN.pm subclass for adding site local modules
**********************************************

NAME
====

   CPAN::Site - CPAN.pm subclass for adding site local modules

SYNOPSIS
========

     perl -MCPAN::Site -e shell

WARNING
=======

   This is not even alpha software and will be made obsolete by CPAN.pm
extensions/plugins some day.

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

   This module virtually adds site specific modules to CPAN. The general
idea is to have a local (pseudo) CPAN server which is asked first. If the
request fails - which is the usual case, CPAN.pm switches to the next URL
in the list pointing to a real CPAN server. The pseudo CPAN server must
serve the files `site/02packages.details.txt.gz' and
`site/01mailrc.txt.gz' which contain the site local extensions to CPAN.
You must make sure that the pseudo server can satisfy the request for
these files since a failure will result in CPAN.pm trying to fetch the
`site/'* files from all the real CPAN servers in your urllist.

   The included *mkpackages* script can be used to generate the local
`02packages.details.txt' file. The script does scan the distribution files
for package names an version numbers. Note that lines looking like VERSION
specifications are evaluated!

   The Makefile.PL will ask you for the URL of your pseudo CPAN server.
This URL added to the front of the urllist of the CPAN.pm configuration
when using this module. Note that rereading the configuraion from the
CPAN.pm shell will cause this URL to be dropped. You must add it again
using

   cpan>` o conf urllist unshift '*your-URL-here*

   in this case.

   To use the module, generate your pseudo CPAN on a anonymous FTP, HTTP
or NFS server:

     mkdirhier ~wwwdata/htdocs/CPAN
     mkpackages ~wwwdata/htdocs/CPAN
     
     Then use C<-MCPAN::Site> instead of C<-MCPAN>

     perl -MCPAN::Site -e shell

Adding modules
==============

     mkdirhier ~wwwdata/htdocs/CPAN/authors/id/ULPFR
     mv /tmp/Telekom-0.101.tar.gz ~wwwdata/htdocs/CPAN/authors/id/ULPFR
     mkpackages ~wwwdata/htdocs/CPAN

AUTHOR
======

   Ulrich Pfeifer <`pfeifer@wait.de'>


File: pm.info,  Node: CPAN/WAIT,  Next: CSS/Parser,  Prev: CPAN/Site,  Up: Module List

adds commands to search a WAIT4CPAN server to the CPAN `shell()'
****************************************************************

NAME
====

   CPAN::WAIT - adds commands to search a WAIT4CPAN server to the CPAN
`shell()'

SYNOPSIS
========

     perl -MCPAN -e shell
     > wq au=wall
     > wr 3
     > wd 3
     > wl 20
     > wh
     > wh wq

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

   *CPAN::WAIT* adds some comands to the CPAN `shell()' to perform
searches on a WAIT server. It connects to a WAIT server using a simple
protocoll resembling NNTP as described in RFC977. It uses the
*WAIT::Client* module to handle this connection. This in turn inherits
from *Net::NNTP* from the `libnet' package. So you need *Net::NNTP* to use
this module.

   If no direct connection to the WAIT server is possible, the modules
tries to connect via your HTTP proxy (as given by the CPAN configuration).
Be warned though that the emulation of the stateful protocol via HTTP is
slow.

   The variable `CPAN::WAIT::TIMEOUT' specifies the number of seconds to
wait for an answer from the server. The default is 20. You may want to set
it to some larger value if you have a slow connection.

   The commands available are:

wh [command]
     Displays a short help message if called without arguments. If you
     provide the name of another command you will get more information on
     this command if available. Currently only wq will be explained.

wl count
     Limit the number of hits returned in a search to count. The limit
     usually is set ot 10 of you don't set it.

wq query
     Send a query to the server.

     Here are some query examples:

          information retrieval               free text query
          information or retrieval            same as above
          des=information retrieval           `information' must be in the description
          des=(information retrieval)         one of them in description
          des=(information or retrieval)      same as above
          des=(information and retrieval)     both of them in description
          des=(information not retrieval)     `information' in description and
                                              `retrieval' not in description
          des=(information system*)           wild-card search
          au=ilia                             author names may be misspelled

     You can build arbitary boolean combination of the above examples.
     Field names may be abbreviated. For further information see
     `http://ls6-www.informatik.uni-dortmund.de/CPAN'

     The result should look like this:

          wq au=wall

          1 8.039 a2p - Awk to Perl translator
          2 8.039 s2p - Sed to Perl translator
          3 8.039 perlipc - Perl interprocess communication (signals, fifos, pipes, safe subprocesses, sockets, and semaphores)
          4 8.039 ExtUtils::DynaGlue - Methods for generating Perl extension files
          5 8.039 h2xs - convert .h C header files to Perl extensions
          6 8.039 Sys::Syslog, openlog, closelog, setlogmask, syslog - Perl interface to the UNIX syslog(3) calls
          7 8.039 h2ph - convert .h C header files to .ph Perl header files
          8 8.039 Shell - run shell commands transparently within perl
          9 8.039 pl2pm - Rough tool to translate Perl4 .pl files to Perl5 .pm modules.
            10 8.039 perlpod - plain old documentation

wr *hit-number*
     Display the Record of hit number *hit-number*:

          wr 1
          
          source          authors/id/CHIPS/perl5.003_24.tar.gz
          headline        a2p - Awk to Perl translator
          size            5643
          docid           data/perl/x2p/a2p.pod

wd *hit-number*
     Fetches the full text from the server and runs perlpod on it. Make
     sure that you have perlpod in your path. Also check if your perlpod
     version can handle absolute pathes. Some older versions ironically do
     not find a document if the full patch is given on the command line.

AUTHOR
======

   Ulrich Pfeifer <`pfeifer@ls6.informatik.uni-dortmund.de'>


File: pm.info,  Node: CSS/Parser,  Next: Cache/Mmap,  Prev: CPAN/WAIT,  Up: Module List

parser for CSS-style syntax
***************************

NAME
====

   CSS::Parser - parser for CSS-style syntax

SYNOPSIS
========

     use CSS::Parser;

     my $css = CSS::Parser->new(
                               handlers => {
                                            css_comment      => \&css_com,
                                            selector_string  => \&sel,
                                            block_start      => \&blk_s,
                                            property         => \&prop,
                                            value            => \&val,
                                            block_end        => \&blk_e,
                                            at_rule          => \&atr,
                                            at_symbol        => \&ats,
                                            error            => \&error
                                            }
                               );

     $css->parse(\$some_css_text);

     sub css_com {
        my $self = shift;
        my $comment = shift;
        print "css comment:\n\t$comment\n";
     }

     ...

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

   The `CSS::Parser' deals simply with fairly loose CSS syntax.  It
doesn't know anything about what it is parsing, for that see other
classes. This allows it to be the base for `CSS::CSSn', `CSS::STTSn' and
any other parser for a css-compatible syntax.

   Chances are, you will want to use one of the existing subclasses or to
subclass it yourself.

   The interface to `CSS::Parser' is:

my $css = CSS::Parser->new([style => $parse_style],[handlers => $hashref_of_handlers]);
     The constructor takes a variety of options provided in a hash.

     style defines the style of parsing that you want from the parser. As
     of now the only style is 'callback' (default), however this may evolve
     in the future.

     handlers specifies a hash of callbacks to be called when a given
     token has been met. Callbacks are CODEREFS. The callback sub will
     receive the parser object as it's first argument, and optionally the
     token when it makes sense (eg: selector_string will be passed the
     selector, but block_start won't receive the '{').

     One may use 'default' to activate them all. Note that you can set a
     callback to the empty string (not undef) if you wish to set a default
     for all but to deactivate that specific callback.

        * html_open_comment

          Called when a <!- comment is seens, no second argument.

        * html_close_comment

          Called when a -> comment is seens, no second argument.

        * css_comment

          Called when a css comment of the form /* text */ is seen.
          Receives the comment with leading /* and trailing */.

        * comment

          Called when any of the above types of comment is seen. Receives
          the comment as is.

        * at_symbol

          Called when an at-symbol (@ident) is seen and is followed by a
          block.  The block is parsed subsequently. Receives the at-symbol.

        * at_rule

          Called when a block-less at-rule (@import url('foo') print;) is
          seen, receives the entire rule (it isn't further tokenized, that
          is the job of the subclass because it requires it to know what
          is expected after the specific at-keyword).

        * selector_string

          Called whenever a selector string is seen and receives the entire
          string as tokenising it further would require knowledge of the
          specific variant of CSS.

        * block_start

          Called when the beginning of a block is seen ({), receives
          nothing.

        * property

          Called when a property is seen, receives the property.

        * value

          Called when a value is seen, receives the value which is not
          parsed to know it's individual components, that belongs to the
          subclass.

        * declaration

          Called with property : $value ;

        * block_end

          Same as block_start, for }.

        * ruleset

          Called with selector_string '{' [declaration;]* '}'

        * error

          Called whenever the parser notices an error, receives what is
          left of the CSS text when the error occurred plus an informative
          message.

        * default

          The use for default is to substitute a standard callback for all
          callbacks that are not defined.

$css->parse( $string_ref );
     Tells the parser to go ahead and parse the provided reference to a
     string. Note that the string will be empty after the parser has
     finished, unless the stylesheet contains an error. It returns 1 upon
     success and undef upon failure.

SEE ALSO
========

   *Note XML/Parser: XML/Parser,, *Note HTML/Parser: HTML/Parser,, *Note
HTML/TreeBuilder: HTML/TreeBuilder,

COPYRIGHT
=========

   Copyright 1998-1999 Robin Berjon (robin@knowscape.com). All rights
reserved.

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


File: pm.info,  Node: Cache/Mmap,  Next: Calendar/CSA,  Prev: CSS/Parser,  Up: Module List

Shared data cache using memory mapped files
*******************************************

NAME
====

   Cache::Mmap - Shared data cache using memory mapped files

SYNOPSIS
========

     use Cache::Mmap;

     $cache=Cache::Mmap->new($filename,\%options);

     $val1=$cache->read($key1);
     $cache->write($key2,$val2);
     $cache->delete($key3);

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

   This module implements a shared data cache, using memory mapped files.
If routines are provided which interact with the underlying data, access to
the cache is completely transparent, and the module handles all the
details of refreshing cache contents, and updating underlying data, if
necessary.

   Cache entries are assigned to "buckets" within the cache file,
depending on the key. Within each bucket, entries are stored apporximately
in order of last access, so that frequently accessed entries will move to
the head of the bucket, thus decreasing access time. Concurrent accesses
to the same bucket are prevented by file locking of the relevent section
of the cache file.

METHODS
=======

Cache::Mmap->new($filename,\%options)
     Creates a new cache object. If the file named by $filename does not
     already exist, it will be created. Various options may be set in
     %options, which affect the behaviour of the cache (defaults in
     parentheses):

    permissions (0600)
          Sets the file permissions for the cache file if it doesn't
          already exist.

    buckets (13)
          Sets the number of buckets inside the cache file. A larger
          number of buckets will give better performance for a cache with
          many accesses, as there will be less chance of concurrent access
          to the same bucket.

    bucketsize (1024)
          Sets the size of each bucket, in bytes. A larger bucket size
          will be needed to store large cache entries. If the bucketsize
          is not large enough to hold a particular entry, it will still be
          passed between the underlying data and the application in its
          entirety, but will not be stored in the cache.

    pagesize (1024)
          Sets the alignment of buckets within the file. The file header
          will be extended to this size, and bucket sizes will be rounded
          up to the nearest multiple.  Choosing a pagesize equal to the
          virtual memory page size of the host system should improve
          performance.

    strings (0)
          If true, cache entries are treated as strings, rather than
          references. This will help performance for string-only caches,
          as no time will be taken to serialize cache entries.

    expiry (0)
          If non-zero, sets the length of time, in seconds, which cache
          entries are considered valid. A new entry will be fetched from
          the underlying data if an expired cache entry would otherwise
          have been returned.

    context (undef)
          This value is passed to the read/write/delete routines below, to
          provide context. This will typically be a database handle, used
          to fetch data from.

    read (undef)
          Provides a code reference to a routine which will fetch entries
          from the underlying data. Called as `$read->($key,$context)',
          this routine should return a list `($found,$value)', where
          `$found' is true if the entry could be found in the underlying
          data, and $value is the value to cache, or undef if not found.
          If this routine is not provided, only values already in the
          cache will ever be returned.

    cachenegative (0)
          If true, even unsuccessful fetches from the underlying data are
          cached. This can be useful to only search the underlying data
          once for each required key.

    write (undef)
          Provides a code reference to a routine which will write cache
          entries into the underlying data. This routine will be called
          after `$cache->write()' is called, to synchronise the underlying
          data with the cache. Called as `$write->($key,$val,$context)'.
          If the routine is not provided, the underlying data will not be
          synchronised after cache writes.

    writethrough (1)
          If true, the write routine above will be called as soon as
          `$cache->write()' is called. This provides immediate
          synchronisation of underlying data and cache contents.

          If false, the write routine will be called for each cache entry
          which no longer fits in its bucket after a cache read or write.
          This provides a write-as-necessary behaviour, which may be more
          efficient than the writethrough behaviour. However, only data
          fetched through the cache will reflect these changes.

    delete (undef)
          Provides a code reference to a routine which will delete items
          from the underlying data. This routine will be called after
          `$cache-'delete()> is called, to synchronise the underlying data
          with the cache. Called as `$cache->delete($key,$cval,$context)',
          where `$cval' is the value currently stored in the cache. If
          this routine is not provided, entries deleted from the cache
          have no effect on the underlying data.

     An alternative to supplying a write routine, is to call
     `$cache->delete()' after updating the underlying data. Note however,
     that in the case of databases, this should be done after committing
     the update, so that a concurrent process doesn't reload the cache
     between being the entry being deleted, and the database updates being
     committed.

$cache->buckets()
     Returns the number of buckets in the cache file. Note that this may be
     different to the number passed to new(), since an existing cache file
     may have been created with different options.

$cache->bucketsize()
     Returns the size of buckets in the cache file. May be different to
     new() parameter.

$cache->pagesize()
     Returns the page size of the cache file. May be different to new()
     parameter.

$cache->strings()
     Returns true if the cache stores strings rather than references. May
     be different to new() parameter.

$cache->expiry()
     Returns the time in seconds cache entries are considered valid for,
     or zero for indefinite validity. May be different to new() parameter.

$cache->writethrough()
     Returns true if items written to the cache are immediately written to
     the underlying data. May be different to new() parameter.

$cache->cachenegative()
     Returns true if items not found in the underlying data are cached
     anyway. May be different to new() parameter.

$cache->context()
     Returns the context data for reads and writes to the underlying data.

$cache->context($context)
     Provides new context data for reads and writes to the underlying data.

$cache->read($key)
     Reads an entry from the cache, or from the underlying data if not
     cached.  Returns the value in scalar context, and `($found,$value)'
     in list context, where `$found' is true if the item was found in
     either the cache or the underlying data.

$cache->write($key,$val)
     Writes an entry into the cache, and depending on new() options, into
     the underlying data.

$cache->delete($key)
     Deletes an entry from the cache, and depending on new() options, from
     the underlying data.

AUTHOR
======

   Peter Haworth <pmh@edison.ioppublishing.com>


File: pm.info,  Node: Calendar/CSA,  Next: Callback,  Prev: Cache/Mmap,  Up: Module List

Perl extension to interface with CDE Calendar Manager
*****************************************************

NAME
====

   Calendar::CSA - Perl extension to interface with CDE Calendar Manager

SYNOPSIS
========

     use Calendar::CSA;
     [etc]

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

   Unfortunately, this module is not documented at this time.

AUTHOR
======

   Kenneth Albanowski <kjahds@kjahds.com>, with the assistance of Bharat
Mediratta <Bharat.Mediratta@Corp.Sun.COM>. Please contact me (Kenneth
Albanowski) about matters pertaining to this module.


File: pm.info,  Node: Callback,  Next: Carp,  Prev: Calendar/CSA,  Up: Module List

object interface for function callbacks
***************************************

NAME
====

   Callback - object interface for function callbacks

SYNOPSIS
========

     use Callback;

     my $callback = new Callback (\&myfunc, @myargs);
     my $callback = new Callback ($myobj, $mymethod, @myargs);

     $callback->call(@some_more_args);

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

   Callback provides a simple interface for function callbacks.  It would
be possible to provide nearly all of the functionality using inline code
references.  Callback was written before inline code references were added
to perl.

   What callback does provide is a simple interface for common situation:
passing around a function.

   When a callback is constructed, a base set of arguments can be
provided.  These function arguments will preceed any arguments added at
the time the call is made.

   There are two forms for the callback constructor, depending on whether
the call is a pure functional call or a method call.  The rule is that if
the first argument is an object, then the second argument is a method name
to be called on that object.

TRACING
=======

     use Callback qw(@callbackTrace);

   If you're writing a debugging routine that provides a stack-dump (for
example, Carp::confess) it is useful to know where a callback was
registered.

     my $ct = 0;
     while (($package, $file, $line, $subname, $hasargs, $wantarray) = caller($i++)) {
         ...

     if ($subname eq 'Callback::call') {
     		print "callback registered $Callback::callbackTrace[$ct]\n";
     		$ct++;
     }
     	}

   Without such code, it becomes very hard to know what's going on.

COPYRIGHT
=========

   Copyright (C) 1994, 2000, David Muir Sharnoff.   All rights reserved.
License hearby granted for anyone to use this module at their own risk.
Please feed useful changes back to muir@idiom.com.


File: pm.info,  Node: Carp,  Next: Carp/Assert,  Prev: Callback,  Up: Module List

warn of errors (from perspective of caller)
*******************************************

NAME
====

   carp    - warn of errors (from perspective of caller)

   cluck   - warn of errors with stack backtrace           (not exported
by default)

   croak   - die of errors (from perspective of caller)

   confess - die of errors with stack backtrace

SYNOPSIS
========

     use Carp;
     croak "We're outta here!";

     use Carp qw(cluck);
     cluck "This is how we got here!";

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

   The Carp routines are useful in your own modules because they act like
die() or warn(), but report where the error was in the code they were
called from.  Thus if you have a routine Foo() that has a carp() in it,
then the carp() will report the error as occurring where Foo() was called,
not where carp() was called.

Forcing a Stack Trace
---------------------

   As a debugging aid, you can force Carp to treat a croak as a confess
and a carp as a cluck across all modules. In other words, force a detailed
stack trace to be given.  This can be very helpful when trying to
understand why, or from where, a warning or error is being generated.

   This feature is enabled by 'importing' the non-existent symbol
'verbose'. You would typically enable it by saying

     perl -MCarp=verbose script.pl

   or by including the string `MCarp=verbose' in the `PERL5OPT' in this
node environment variable.

BUGS
====

   The Carp routines don't handle exception objects currently.  If called
with a first argument that is a reference, they simply call die() or
warn(), as appropriate.


File: pm.info,  Node: Carp/Assert,  Next: Carp/Heavy,  Prev: Carp,  Up: Module List

executable comments
*******************

NAME
====

   Carp::Assert - executable comments

SYNOPSIS
========

     # Assertions are on.
     use Carp::Assert;

     $next_sunrise_time = sunrise();

     # Assert that the sun must rise in the next 24 hours.
     assert(($next_sunrise_time - time) < 24*60*60) if DEBUG;

     # Assertions are off.
     no Carp::Assert;

     $next_pres = divine_next_president();

     # Assert that if you predict Dan Quayle will be the next president
     # your crystal ball might need some polishing.  However, since
     # assertions are off, IT COULD HAPPEN!
     shouldnt($next_pres, 'Dan Quayle') if DEBUG;

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

     "We are ready for any unforseen event that may or may not
     occur."
         - Dan Quayle

   Carp::Assert is intended for a purpose like the ANSI C library
assert.h.  If you're already familiar with assert.h, then you can probably
skip this and go straight to the FUNCTIONS section.

   Assertions are the explict expressions of your assumptions about the
reality your program is expected to deal with, and a declaration of those
which it is not.  They are used to prevent your program from blissfully
processing garbage inputs (garbage in, garbage out becomes garbage in,
error out) and to tell you when you've produced garbage output.  (If I was
going to be a cynic about Perl and the user nature, I'd say there are no
user inputs but garbage, and Perl produces nothing but...)

   An assertion is used to prevent the impossible from being asked of your
code, or at least tell you when it does.  For example:

     # Take the square root of a number.
     sub my_sqrt {
         my($num) = shift;

     # the square root of a negative number is imaginary.
     assert($num >= 0);

     return sqrt $num;
         }

   The assertion will warn you if a negative number was handed to your
subroutine, a reality the routine has no intention of dealing with.

   An assertion should also be used a something of a reality check, to
make sure what your code just did really did happen:

     open(FILE, $filename) || die $!;
     @stuff = <FILE>;
     @stuff = do_something(@stuff);

     # I should have some stuff.
     assert(scalar(@stuff) > 0);

   The assertion makes sure you have some @stuff at the end.  Maybe the
file was empty, maybe do_something() returned an empty list... either way,
the assert() will give you a clue as to where the problem lies, rather
than 50 lines down when you print out @stuff and discover it to be empty.

   Since assertions are designed for debugging and will remove themelves
from production code, your assertions should be carefully crafted so as to
not have any side-effects, change any variables or otherwise have any
effect on your program.  Here is an example of a bad assertation:

     assert($error = 1 if $king ne 'Henry');  # Bad!

   It sets an error flag which may then be used somewhere else in your
program. When you shut off your assertions with the $DEBUG flag, $error
will no longer be set.

   Here's another bad example:

     assert($next_pres ne 'Dan Quayle' or goto Canada);  # Bad!

   This assertion has the side effect of moving to Canada should it fail.
This is a very bad assertion since error handling should not be placed in
an assertion, nor should it have side-effects.

   In short, an assertion is an executable comment.  For instance, instead
of writing this

     # $life ends with a '!'
     $life = begin_life();

   you'd replace the comment with an assertion which *enforces* the
comment.

     $life = begin_life();
     assert( $life =~ /!$/ );

FUNCTIONS
=========

assert
          assert(STATEMENT) if DEBUG;

     assert's functionality is effected by compile time value of the DEBUG
     constant.  If DEBUG is true, assert will function as below.  If DEBUG
     is false the assert function will compile itself out of the program.
     See `Debugging vs Production' in this node for details.

     Give assert an expression, assert will Carp::confess() if that
     expression is false, otherwise it does nothing.  (DO NOT use the
     return value of assert for anything, I mean it... really!).

     The error from assert will look something like this:

          Assert failed
                  Carp::Assert::assert(0) called at prog line 23
                  main::foo called at prog line 50

     Indicating that in the file "prog" an assert failed inside the
     function main::foo() on line 23 and that foo() was in turn called from
     line 50 in the same file.

should
shouldnt
          should  ($this, $shouldbe)   if DEBUG;
          shouldnt($this, $shouldntbe) if DEBUG;

     Similar to assert(), it is specially for simple "this should be that"
     or "this should be anything but that" style of assertions.

     Due to Perl's lack of a good macro system, assert() can only report
     where something failed, but it can't report *what* failed or how.
     should() and shouldnt() can produce more informative error messages:

          Assert failed:  'this' should be 'that'!
                  Carp::Assert::should('this', 'that') called at moof line 29
                  main::foo() called at moof line 58

     So this:

          should($this, $that) if DEBUG;

     is similar to this:

          assert($this eq $that) if DEBUG;

     except for the better error message.

     Currently, should() and shouldnt() can only do simple eq and ne tests
     (respectively).  Future versions may allow regexes.

Debugging vs Production
=======================

   Because assertions are extra code and because it is sometimes necessary
to place them in 'hot' portions of your code where speed is paramount,
Carp::Assert provides the option to remove its assert() calls from your
program.

   So, we provide a way to force Perl to inline the switched off assert()
routine, thereby removing almost all performance impact on your production
code.

     no Carp::Assert;  # assertions are off.
     assert(1==1) if DEBUG;

   DEBUG is a constant set to 0.  Adding the 'if DEBUG' condition on your
assert() call gives perl the cue to go ahead and remove assert() call from
your program entirely, since the if conditional will always be false.

   (This is the best I can do without requiring Filter::cpp)

   Another way to switch off all asserts, system wide, is to define the
NDEBUG or the PERL_NDEBUG environment variable.

   You can safely leave out the "if DEBUG" part, but then your assert()
function will always execute (and its arguments evaluated).  Oh well.

Differences from ANSI C
=======================

   assert() is intended to act like the function from ANSI C fame.
Unfortunately, due to perl's lack of macros or strong inlining, it's not
nearly as unobtrusive.

   Well, the obvious one is the "if DEBUG" part.  This is cleanest way I
could think of to cause each assert() call and its arguments to be removed
from the program at compile-time, like the ANSI C macro does.

   Also, this version of assert does not report the statement which
failed, just the line number and call frame via Carp::confess.  You can't
do `assert('$a == $b')' because $a and $b will probably be lexical, and
thus unavailable to assert().  But with Perl, unlike C, you always have
the source to look through, so the need isn't as great.

ENVIRONMENT
===========

NDEBUG
     Defining NDEBUG switches off all assertions.  It has the same effect
     as changing "use Carp::Assert" to "no Carp::Assert" but it effects all
     code.

PERL_NDEBUG
     Same as NDEBUG and will override it.  Its provided to give you
     something which won't conflict with any C programs you might be
     working on at the same time.

BUGS, CAVETS and other MUSINGS
==============================

   Someday, Perl will have an inline pragma, and the `if DEBUG'
bletcherousness will go away.

   I really need to figure a way to get it to return the given statement
in the assertion.  should() and shouldnt() is a start.  Maybe
B::Deparse... would assert({$this eq $that}) be too annoying?

   Yes, there is a `shouldn't' routine.  It mostly works, but you must put
the `if DEBUG' after it.

AUTHOR
======

   Michael G Schwern <schwern@pobox.com>


File: pm.info,  Node: Carp/Heavy,  Next: Carp/Notify,  Prev: Carp/Assert,  Up: Module List

Carp guts
*********

NAME
====

   Carp::Heavy - Carp guts

SYNOPIS
=======

   (internal use only)

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

   No user-serviceable parts inside.


File: pm.info,  Node: Carp/Notify,  Next: CfgTie/CfgArgs,  Prev: Carp/Heavy,  Up: Module List

Loudly complain in lots of places when things break badly
*********************************************************

NAME
====

   Carp::Notify - Loudly complain in lots of places when things break badly

AUTHOR
======

   Jim Thomason thomasoniii@yahoo.com

SYNOPSIS
========

   Use it in place of die or croak, or warn or carp.

     #with Carp;
     use Carp;
     if ($something_a_little_bad) { carp("Oh no, a minor error!")};
     if ($something_bad) { croak ("Oh no an error!")};

     #with Carp::Notify;
     use Carp::Notify;
     if (something_a_little_bad) {notify("Oh no, a minor error!")};
     if ($something_bad) { explode ("Oh no an error!")};

REQUIRES
========

   Perl 5.004, Socket (for emailing)

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

   Carp::Notify is an error reporting module designed for applications
that are running unsupervised (a CGI script, for example, or a cron job).
If a program has an explosion, it terminates (same as die or croak or
exit, depending on preference) and then emails someone with useful
information about what caused the problem.  Said information can also be
logged to a file.  If you want the program to tell you something about an
error that's non fatal (disk size approaching full, but not quite there,
for example), then you can have it notify you of the error but not
terminate the program.

   Defaults are set up within the module, but they can be overridden once
the module is used, or as individual explosions take place.

BUILT IN STUFF
==============

Using the module
     use Carp::Notify;

     will require and import the module, same as always.  What you decide
     to import it with is up to you.  You can choose to import additional
     functions into your namespace, set up new default values, or give it
     a list of variables to store.

     Carp::Notify will always export the explode function and the notify
     function.  Carp always exports carp, croak, and confess, so I figure
     that I can get away with always exporting explode and notify.  Nyaah.

     Be sure that you set your default variables before using it!

    make_storable
          if this is an import argument, it will export the make_storable
          function into your namespace.  See make_storable, below.

    make_unstorable
          If this is an import argument, it will export the
          make_unstorable function into your namespce.  See
          make_unstorable, below.

    croak
          If this is an import argument, it will override the croak
          function in your namespace and alias it to explode.  That way
          you can switch all of your croaks to explodes by just changing
          how you use your module, and not all of your code.

    carp
          If this is an import argument, it will override the carp
          function in your namespace and alias it to notify.  That way you
          can switch all of your carps to notifies by just changing which
          module you use, and not all of your code.

    (log_it|email_it|store_vars|stack_trace|store_env|email|log_file|smtp|die_to_stdout|die_quietly|death_message)
          Example:

               use Carp::Notify (
               	"log_it" => 1,
               	"email_it => 0,
               	"email" => 'thomasoniii@yahoo.com'
               );

          These are hash keys that allow you to override the
          Carp::Notify's module defaults.  These can also all be
          overloaded explicitly in your explode() calls, but this allows a
          global modification.

         log_it
               Flag that tells Carp::Notify whether or not to log the
               explosions to the log file

         log_file
               Overrides the default log file.  This file will be opened
               in append mode and the error message will be stored in it,
               if log_it is true.

               If you'd like, you can give log_file a reference to a glob
               that is an open filehandle instead of a scalar containing
               the log name.  This is most useful if you want to redirect
               your error log to STDERR or to a pipe to a program.

               Be sure to use globrefs only explicitly in your call to
               explode, or to wrap the definition of the filehandle in a
               begin block before using the module.  Otherwise, you'll be
               trying to log to a non-existent file handle and
               consequently won't log anything.  That'd be bad.

         email_it
               Flag that tells Carp::Notify whether or not to email a user
               to let them know something broke

         email
               Overrides the default email address.  This is whoever the
               error message will get emailed to if U<email_it> is true.

         smtp
               Allows you to set a new SMTP relay for emailing

         store_vars
               Flag that tells Carp::Notify whether or not to list any
               storable variables in the error message.  See storable
               variables, below.

         stack_trace
               Flag that tells Carp::Notify whether or not to do a call
               stack trace of every function call leading up to the
               explosion.

         store_env
               Flag that tells Carp::Notify whether or not to store the
               environment variables in the error message.

         die_to_stdout
               Allows you to terminate your program by displaying an error
               to STDOUT, not to STDERR.

         die_quietly
               Terminates your program without displaying any message to
               STDOUT or STDERR.  =back

              death_message
                    The message that is printed to the appropriate
                    location, unless we're dying quietly.  =back

              (*storable variable*)
                    A variable name within single quotes will tell the
                    Carp::Notify module that you want to report the
                    current value of that variable when the explosion
                    occurs.  Carp::Notify will report an error if you try
                    to store a value that is undefined, if you had
                    accidentally typed something in single quotes, for
                    instance.  For example,

                         use Carp::Notify ('$scalar', '@array');
                         
                         $scalar = "some_value";
                         @array = qw(val1 val2 val3);
                         
                         explode("An error!");
                         
                         will write out the values "$scalar : some_value" and "@array : val1 val2 val3" to the log file.

                    This can also only be used to store global variables.
                    Dynamic or lexical variables need to be explicitly
                    placed in explode() calls.

                    You can store variables from other packages if you'd
                    like:

                    use Carp::Notify ('$other_package::scalar',
                    '@some::nested::package::array');

                    Only global scalars, arrays, and hashes may be stored.

         make_storable
               Makes whatever variables it's given storable.  See
               *storable variables*, above.

                    make_storable('$new_scalar', '@different_array');

         make_unstorable
               Stops whatever variables it's given from being stored.  See
               *storable variables*, above.

                    make_unstorable('$scalar', '@different_array');

         explode
               explode is where the magic is.  It's exported into the
               calling package by default (no point in using this module
               if you're not gonna use this function, after all).

               You can override your default values here (see *Using the
               module above*), if you'd like, and otherwise specify as
               many error messages as you'd like to show up in your logs.

                    #override who the mail's going to, and the log file.
                    explode("email" => "thomasoniii@yahoo.com", log_file => "/home/jim/jim_explosions.log", "A terrible error: $!");

                    #Same thing, but with a globref to the same file
                    open (LOG, ">>/home/jim/jim_explosions.log");
                    explode("email" => "thomasoniii@yahoo.com", log_file => \*LOG, "A terrible error: $!");

                    #don't log.
                    explode ("log_it" => 0, "A terrible error: $!");
                    
                    #keep the defaults
                    explode("A terrible error: $!", "And DBI said:  $DBI::errstr");

         notify
               notify is to explode as warn is to die.  It does everything
               exactly the same way, but it won't terminate your program
               the way that an explode would.

FAQ
===

   *So what's the point of this thing?*

   It's for programs that need to keep running and that need to be fixed
quickly when they break.

   *But I like Carp*

   I like Carp too.  :)

   This isn't designed to replace Carp, it serves a different purpose.
Carp will only tell you the line on which your error occurred.  While this
i helpful, it doesn't get your program running quicker and it doesn't help
you to find an error that you're not aware of in a CGI script that you
think is running perfectly.

   Carp::Notify tells you ASAP when your program breaks, so you can
inspect and correct it quicker.  You're going to have less downtime and
the end users will be happier with your program because there will be
fewer bugs since you ironed them out quicker.

   *Wow.  That was a real run-on sentence*

   Yeah, I know.  That's why I'm a programmer and not an author.  :)

   *What about CGI::Carp?*

   That's a bit of a gray area.  Obviously, by its name, CGI::Carp seems
designed for CGI scripts, whereas Carp::Notify is more obvious for
anything (cron jobs, command line utilities, as well as CGIs).

   Carp::Notify also can store more information with less interaction from
the programmer.  Plus it will email you, if you'd like to let you know
that something bad happened.

   As I understand it, CGI::Carp is a subset feature-wise of Carp::Notify.
If CGI::Carp is working fine for you, great continue to use it.  If you
want more flexible error notification, then try out Carp::Notify.

   *But I can send email with CGI::Carp by opening up a pipe to send mail
and using that as my error log.  What do you have to say about that?*

   Good for you.  I can too.  But most people that I've interacted with
either don't have the know-how to do that or just plain wouldn't have
thought of it.  Besides, it's still more of a hassle than just using
Carp::Notify.

   *Why are your stored variables kept in an array instead of a hash?
Hashes are quicker to delete from, after all*

   While it is definitely true that variables can be unstored a little
quicker in a hash, I figured that stored variables will only rarely be
unstored later.  Arrays are quicker for storing and accessing the items
later.   I'll live with the slight performance hit for the rarer case.

   *Can I store variables that are in another package from the one that
called Carp::Notify?*

   You betcha.  Just prepend the classpath to the variable name, same as
you always have to to access variables not in your name space.  If the
variable is already in your name space (you imported it), you don't need
the classpath since explode will just pick it up within your own namespace.

   *Can I store local or my variables?*

   Not in the use statement, but you can in an explicit explode.

   *Are there any bugs I should be aware of?*

   Only if you're annoying.  If you import explode into your package, then
subclass it and export explode back out it won't correctly pick up your
stored variables unless you fully qualified them with the class path
($package::variable instead of just $variable)

   Solution?  Don't re-export Carp::Notify.  But you already knew that you
should juse re-use it in your subclass, right?

   *Could I see some more examples?*

   Sure, that's the next section.

   *Okay, you've convinced me.  What other nifty modules have you
distributed?*

   Mail::Bulkmail and Text::Flowchart.

   *Was that a shameless plug?*

   Why yes, it was.

Examples
========

     #store $data, do email the errors, and alias croak => explode
     use Carp::Notify ('$data', 'email_it' => 1, "croak");

     #email it to a different address, and don't log it.
     use Carp::Notify ("email" => 'thomasoniii@yahoo.com', 'log_it' => 0);

     #die with an explosion.
     explode("Ye gods!  An error!");
     
     #explode, but do it quietly.
     explode ("die_quietly" => 1, "Ye gods!  An error!");
     
     #notify someone of a problem, but keep the program running
     notify ("Ye gods!  A little error!");

Version History
===============

   v1.00 - August 10, 2000 - Changed the name from Explode to
Carp::Notify.  It's more descriptive and I don't create a new namespace.

   v1.00 FC1 - June 9, 2000 - First publically available version.

COPYRIGHT (again)
=================

   Copyright (c) 2000 James A Thomason III (thomasoniii@yahoo.com). All
rights reserved.  This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.

CONTACT INFO
============

   So you don't have to scroll all the way back to the top, I'm Jim
Thomason (thomasoniii@yahoo.com) and feedback is appreciated.  Bug
reports/suggestions/questions/etc.  Hell, drop me a line to let me know
that you're using the module and that it's made your life easier.  :-)


File: pm.info,  Node: CfgTie/CfgArgs,  Next: CfgTie/Cfgfile,  Prev: Carp/Notify,  Up: Module List

Configuration module for parsing commandline arguments
******************************************************

NAME
====

   `CfgTie::CfgArgs' - Configuration module for parsing commandline
arguments

SYNOPSIS
========

   This module is meant to help create useful configuration tools and
utilities.

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

   A tool to allow many of your computer's subsystems to be configured.
This module parses commandline arguments.  It is provided to help create a
standardized lexicon.

Scope controls and settings
---------------------------

   To specify how much of your system should be affected by the change in
settings:

     --scope=session|application|user|group|system

   In addition, each of the individual parts can specified (instead of
their defaults):

`--application='NAME
`--application 'NAME
     This specifies the application.

`--user='NAME
`--user 'NAME
     This specifies the user name.

`--group='NAME
`--group 'NAME
     This specifies the group name.

Operations on variables
-----------------------

   The specific operation to be done:

     --op=set|unset|remove|delete|exists|fetch|get|copy|rename

   or:

     --copy   name1=name2 name3=name4 ...
     --exists name1 name2 name3 ...
     --test   name1=value1 name2=value2 ...
             --unset  name1 name2 ...

`--delete 'NAME
`--delete='NAME
     This will remove the entry specified by NAME.  NAME may be a regular
     expression.

`--fetch 'NAME
`--fetch='NAME
     This will retrieve the information associated with NAME.  If NAME is a
     regular expression, information will retrieved for every entry that
     matches the pattern.

`--remove 'NAME
`--remove='NAME
     Like delete above, this will remove the entry specified by NAME.  NAME
     may be a regular expression.

`--rename' *NAME-NEW*=*NAME-OLD*
     This will change all of the occurrences or references that match
     *NAME-OLD* to the newer form of *NAME-NEW*.  This may be a regular
     expression, similar to;

          s/NAME-OLD/NAME-NEW/

`--set' NAME=VALUE
     This will create an entry called NAME with a setting of VALUE.

   The variable names are optional, and can be explicitly specified:

     --name

   Otherwise it is assumed to be the first no flag parameter.

   Similarly, the value can be specified

     --value

Other flags
-----------

`--file 'FILE
`--file='FILE
     This specifies the configuration file to employ.  If none is
     specified, the default for the particular subsystem will be used
     instead.

`--comment 'COMMENT
`--comment='COMMENT
     This provides a text comment on what changes are being made.

     -n,
     --dry-run,
     --just-print
     --recon

   With these flags, the utility program *should not modify any files*.
Instead, it should merely document what changes it would make, what
programs it would run, etc.

     --copyright
             --help
     --info
     --information
     --manual
     --verbose
     --version
             --warranty

Exit value
----------

   If the operation exists the return value is zero, otherwise it is
nonzero.

Return from parsing
-------------------

   The hash return:

     {
        SCOPE=> session,application,user,group,system
        OP  => COPY, RENAME, STORE, DELETE, FETCH, or EXISTS
        KEY =>
        VALUE=>
     }

AUTHOR
======

   Randall Maas (`mailto:randym@acm.org' in this node, `http:' in this
node)


