NAME
   Data::CTable - Read, write, manipulate tabular data

SYNOPSIS
           ## Read some data files in various tabular formats
           use          Data::CTable;
           my $People = Data::CTable->new("people.merge.mac.txt");
           my $Stats  = Data::CTable->new("stats.tabs.unix.txt");

           ## Clean stray whitespace in fields
           $People->clean_ws();
           $Stats ->clean_ws();

           ## Retrieve columns
           my $First = $People->col('FirstName');
           my $Last  = $People->col('LastName' );

           ## Calculate a new column based on two others
           my $Full  = [map {"$First->[$_] $Last->[$_]"} @{$People->all()}];

           ## Add new column to the table
           $People->col(FullName => $Full);

           ## Another way to calculate a new column
           $People->col('Key');
           $People->calc(sub {no strict 'vars'; $Key = "$Last,$First";});

           ## "Left join" records matching Stats:PersonID to People:Key
           $Stats->join($People, PersonID => 'Key');

           ## Find certain records
           $Stats->select_all();
           $Stats->select(Department => sub {/Sale/i  });  ## Sales depts
           $Stats->omit  (Department => sub {/Resale/i});  ## not Resales
           $Stats->select(UsageIndex => sub {$_ > 20.0});  ## high usage

           ## Sort the found records
           $Stats->sortspec('DeptNum'   , {SortType => 'Integer'});
           $Stats->sortspec('UsageIndex', {SortType => 'Number' });
           $Stats->sort([qw(DeptNum UsageIndex Last First)]);

           ## Make copy of table with only found/sorted data, in order
           my $Report = $Stats->snapshot();

           ## Write an output file
           $Report->write(_FileName => "Rept.txt", _LineEnding => "mac");

           ## Print a final progress message.
           $Stats->progress("Done!");

           ## Dozens more methods and parameters available...

OVERVIEW
   Data::CTable is a comprehensive utility for reading, writing,
   manipulating, cleaning and otherwise transforming tabular data. The
   distribution includes several illustrative subclasses and utility
   scripts.

   A Columnar Table represents a table as a hash of data columns, making it
   easy to do data cleanup, formatting, searching, calculations, joins, or
   other complex operations.

   The object's hash keys are the field names and the hash values hold the
   data columns (as array references).

   Tables also store a "selection" -- a list of selected / sorted record
   numbers, and a "field list" -- an ordered list of all or some fields to
   be operated on. Select() and sort() methods manipulate the selection
   list. Later, you can optionally rewrite the table in memory or on disk
   to reflect changes in the selection list or field list.

   Data::CTable reads and writes any tabular text file format including
   Merge, CSV, Tab-delimited, and variants. It transparently detects,
   reads, and preserves Unix, Mac, and/or DOS line endings and tab or comma
   field delimiters -- regardless of the runtime platform.

   In addition to reading data files, CTable is a good way to gather,
   store, and operate on tabular data in memory, and to export data to
   delimited text files to be read by other programs or interactive
   productivity applications.

   To achieve extremely fast data loading, CTable caches data file contents
   using the Storable module. This can be helpful in CGI environments or
   when operating on very large data files. CTable can read an entire
   cached table of about 120 megabytes into memory in about 10 seconds on
   an average mid-range computer.

   For simple data-driven applications needing to store and quickly
   retrieve simple tabular data sets, CTable provides a credible
   alternative to DBM files or SQL.

   For data hygiene applications, CTable forms the foundation for writing
   utility scripts or compilers to transfer data from external sources,
   such as FileMaker, Excel, Access, personal organizers, etc. into
   compiled or validated formats -- or even as a gateway to loading data
   into SQL databases or other destinations. You can easily write short,
   repeatable scripts in Perl to do reporting, error checking, analysis, or
   validation that would be hard to duplicate in less-flexible application
   environments.

   The data representation is simple and open so you can directly access
   the data in the object if you feel like it -- or you can use accessors
   to request "clean" structures containing only the data or copies of it.
   Or you can build your own columns in memory and then when you're ready,
   turn them into a table object using the very flexible new() method.

   The highly factored interface and implementation allow fine-grained
   subclassing so you can easily create useful lightweight subclasses.
   Several subclasses are included with the distribution.

   Most defaults and parameters can be customized by subclassing,
   overridden at the instance level (avoiding the need to subclass too
   often), and further overridden via optional named-parameter arguments to
   most major method calls.

 Similar / related modules on CPAN

   The Data::Table module by Yingyao Zhou & Guangzhou Zou offers similar
   functionality, but uses a different underlying data representation
   (2-dimensional array), and has a somewhat different feature set. Check
   it out. Maybe you will prefer it for your application.

           http://search.cpan.org/search?mode=module&query=Data::Table

   The Data::ShowTable module renders tables in various viewable formats.
   CTable relies on ShowTable's ShowBoxTable method to implement its own
   format() and out() methods.

           http://search.cpan.org/search?mode=module&query=Data::ShowTable

 Prerequisites

   The CTable documentation, source code, and examples assume familiarity
   with large nested data structures, object-oriented syntax and
   terminology, and comfort working with array and hash references and
   array and hash slice syntax.

   See the perlref man page for more on these topics.

 How to learn more

   Dozens more methods, parameters, and examples are described below.

   See the full source code in CTable.pm.

   Or, after installing, read the man page using:

           man     Data::CTable
           perldoc Data::CTable

   See the eg/ (examples) folder in the Data::CTable distribution and the
   test.pl script for scripts demonstrating every CTable method.

   For latest version and other news, check the Data::CTable home page:

           http://christhorman.com/projects/perl/Data-CTable/

   Or search CPAN:

           http://search.cpan.org/search?mode=module&query=Data::CTable

INSTALLATION
   Using CPAN module:

           perl -MCPAN -e 'install Data::CTable'

   Or manually:

           tar xzvf Data-CTable*gz
           cd Data-CTable-?.??
           perl Makefile.PL
           make
           make test
           make install

INCLUDED SUBCLASSES AND UTILITIES
   In addition to the module itself, there are a number of subclasses and
   simple utilities included with the Data::CTable distribution.

 Subclases

   The Data::CTable distribution includes these example subclasses. Each is
   installed in your Perl environment along with the main module, and so
   may be used by your scripts. Each has its own man/perldoc page
   containing more detail.

   Data::CTable::ProgressLogger is a subclass that logs all progress
   messages to a list within the object itself rather than (merely) echoing
   them to STDERR. Later, you may retrieve and examine the list.

   Data::CTable::Script is a virtual subclass that includes class and
   object methods that make it easy to write a simple interactive
   command-line program that parses options and outputs a table.

   Data::CTable::Listing is a very useful subclass of Data::CTable::Script
   that implements a souped-up Unix-like "ls" (file listing) command -- it
   first gets an optionally-recursive listing of any number of files and/or
   directories, builds a list of their full absolute or relative paths,
   then build a Data::CTable::Listing object that contains all the paths,
   plus about 25+ other pieces of useful information about each file or
   directory.

   The "tls" utility, below, is simply a command-line cover for this class,
   but you could use this class in your own scripts in order to get
   detailed file listings.

 Utilities

   Each of these utilities is provided mainly so you can see mature
   examples of how to use Data::CTable in real-world scripts.

   But each is also genuinely useful, too, and you may enjoy adding them to
   your regular bag of tricks or using them as an easily-modifiable basis
   for scripts of your own.

   On most systems, these will be installed in an appropriate directory in
   your path when you install CTable, and hence will be executable just by
   typing their file name. (On Windows, they'll be wrapped by a .bat file
   and installed in C:\Perl\bin or equivalent. On *nix, they'll be in
   /usr/bin/ or equivalent.)

   tls is a command-line utility that wraps Data::CTable::Listing to
   implement a variant on the classic Unix "ls" command in which an
   internal CTable object is used to hold and calculate a very large amount
   of meta-data about each file and directory and then output that data in
   formatted tables, or as any kind of delimited text file, and with much
   more flexibility and control over included data, and sort and sub-sort
   order than with ls.

   tshow is a command-line utility that reads each of its arguments as a
   Data::CTable file and then calls the out() method to display its entire
   contents. (Warning: out() is slow with very large data sets.)

   getweather is a command-line utility that takes a US zip code, grabs the
   local weather report from a popular weather web site and uses a CTable
   object to store, process, and clean, and present the table of weather
   data that results in a simple text format.

CREATING TABLE OBJECTS
           ## Create an object / read file(s) / override params

           use  Data::CTable;

           $t = Data::CTable->new()
           $t = Data::CTable->new($File)
           $t = Data::CTable->new($File1, $File2....)
           $t = Data::CTable->new($Params)
           $t = Data::CTable->new($Params, $File1)
           $t = Data::CTable->new($Params, $File1, $File2....)

           ## Internal initializer (subclassable): called for you by new()

           $t->initialize()

   If the first argument to new() is a hash ref, it is the $Params hash of
   initial parameters and/or data columns which, if supplied will form the
   starting point for the object being created. Any non-hash and/or further
   arguments to new() are treated as file names to be opened.

   If supplied, data in the $Params hash will be shallowly copied -- the
   original hash object passed will not be used, but any sub-structures
   within it will now "belong" to the resulting new object which will feel
   free to manipulate them or discard them.

   Then, any parameters not supplied (usually most of them) will be
   defaulted for you because new() will call the internal method
   initialize() before the object is finished and returned.

   See the PARAMETER REFERENCE section below for the parameters you can
   choose to supply or have defaulted for you.

   Any file name arguments will be read and appended into a single object.
   If any of the files fails to be read, then new() will fail (return a
   false value) and no object will be created.

   initialize() makes sure there is a legal and consistent value for every
   internal parameter in the object. Generally, initialize() leaves alone
   any parameters you supplied to new(), and simply sets default values for
   any that were not yet supplied.

   You should never need to call initialize() directly.

   After calling initialize(), new() then calls the append_files_new()
   method to process the filename arguments. This method then calls read()
   on the first filename, and then append_file on all subsequent file
   names, appending them to the first, in sequence.

   See append() for an explanation of how the data from multiple files is
   combined into a single table.

 Advanced: Using a template object

           ## Calling new() with a template object

           $v =           $t->new()
           $v =           $t->new($File)
           $v =           $t->new($File1, $File2....)
           $v =           $t->new($Params)
           $v =           $t->new($Params, $File1)
           $v =           $t->new($Params, $File1, $File2....)

   You can also call $t->new() to use an existing object, $t, as a template
   for the new object. $t->new() will create a new object of the same class
   or subclass as the template object. Furthermore, the template object, if
   provided, will be used as a starting point for the resulting object --
   in fact, it will initially share shallow copies of all data columns, if
   any, and all internal parameters and data structures, if any.

   This advanced shared-data technique could be used to create two separate
   table objects that share and operate on the same underlying data columns
   in memory but have different custom field lists, custom selections, sort
   behavior, etc. But don't do this unless you're sure you understand what
   you're doing, because changing data in one table would change it in the
   other.

PARAMETER REFERENCE
   The parameters listed here are recognized by new(), initialize(), and by
   many functions that use the named-parameter calling convention, such as
   read(), write(), sort(), and others.

   Any parameter listed may be specified when using new().

   Most parameters should not be directly accessed or manipulated once the
   object has been created, except those that have appropriate accessor
   methods described throughout in this documentation.

   Each parameter in the lists below is listed along with its defaulting
   logic as performed by new() via initialize().

 Custom field list and custom selection (record list)

   _FieldList ||= undef;
       This is the ordered list (array reference) of columns / fields
       present in the object. It is set by read() to reflect the names and
       order of the fields encountered or actually read from in the
       incoming data file, if any. Initially this list is undefined, and if
       removed or left undefined, then the de-facto field list will be a
       list of all columns present in the table object, in alphabetical
       order (see fieldlist() and fieldlist_all()).

       Normally, all fields present in the table object would be listed in
       the field list.

       However, this parameter may be set in the object (or overridden in
       named-parameter function calls like read(), write(), etc.) to cause
       a subset of fields to be read, written or otherwise used. If a
       subset field list is specified before reading a data file, then ONLY
       fields listed will be read -- this is a way to read just certain
       fields from a very large file, but may not always be what you want.

       Specifying the field list before calling read() is required if the
       data file has no header row giving names to its fields -- the names
       you specify in the field list, in order, will be applied to the data
       file being read. See the _HeaderRow parameter, below.

       If a subset field list is used after columns are already loaded in
       memory, the columns not listed in the field list will still be
       present in the object (and can be listed by calling
       fieldlist_all()), but they will be omitted from most operations that
       iterate over fields.

   _Selection ||= undef;
       This is a list of the record numbers of "selected" records in the
       table, possibly indicating sorted order.

       If absent, then all records are considered to be selected, in
       "natural" order -- i.e. the order they occur in the file.

       You can create and set your own selection list or get and modify an
       existing one. Deleting it resets the selection (for example, by
       calling select_all()).

       Calling sort() will create a _Selection if none existed. Otherwise
       it operates by modifying the existing _Selection, which may be a
       subset of all record numbers.

 Cache behavior controls

   See sections related to Cacheing, below.

   _CacheOnRead = 1 unless exists
       Boolean: whether data files read by the read() method should be
       cached after reading. Once cached, the data will be read from the
       cache instead of the original file the NEXT TIME READ() IS CALLED,
       but only if: 1) the cache file is found, and 2) its date is later
       than the original. Otherwise, the cache file is ignored or
       re-written. Cacheing can be up to 10x faster than parsing the file,
       so it's almost always worth doing in any situation where you'll be
       reading a data file more often than writing it.

       This parameter defaults to true.

   _CacheOnWrite = 0 unless exists
       Boolean: whether tables written by the write() method should be
       cached after writing. This defaults to false on the assumption that
       the program won't need to re-read a file it just wrote. However,
       this behavior would be useful if a later step in your program or
       another program will be reading the file that was written and would
       benefit from having the cacheing already done. Cacheing a file after
       writing is quite fast since the data is already in memory and of
       course it speeds up subsequent read() operations by up to 10x.

   _CacheExtension = ".cache" unless exists
       This is the file name extension that is added to a file's name to
       determine the name of its corresponding cache file. (First, any
       existing extension, if any, is removed.) If this extension is empty,
       then the cache file will be named the same as the original assuming
       the cache file is being stored in a different directory. (See next
       setting.)

   _CacheSubDir = "cache" unless exists
       This is the absolute or relative path to the subdirectory that
       should be used to store the cache files. The default value is the
       relative path to a directory called "cache". Relative paths will be
       appended to the directory path containing the original file being
       read.

       Absolute cache paths (such as /tmp or c:\temp\) can also be used.

       Override _CacheExtension and _CacheSubdir in a subclass, in each
       object, or in each call to read() or write() in order to have the
       cache files stored elsewhere. But remember: unless you use the same
       cache settings next time you read the same file, the cache files
       will be orphaned.

 Progress routine / setting

   _Progress = undef unless exists
       The _Progress setting controls the routing of diagnostic messages.
       Four possible settings are recognized:

               undef (default)        The class's progress settings are used.
               subroutine reference   Your own custom progress routine.
               true                   Built-in progress_default() method used.
               0/false                No progress messages for this object.

       See the PROGRESS section for a description of the interface of
       custom progress routines and for details on how the builtin one
       works.

 File format settings

   _LineEnding ||= undef;
       _LineEnding indicates the line ending string or setting to be used
       to read a file, the setting that actually *was* used to read a file,
       and/or the line ending that will be used to write a file.

       Set this parameter to force a particular encoding to be used.

       Otherwise, leave it undef. The program will Do What You Mean.

       If _LineEnding is undef when read() is called, read() will try to
       guess the line ending type by inspecting the first file it reads.
       Then it will set this setting for you. It can detect DOS, Unix, and
       Mac line endings.

       If _LineEnding is undef when write() is called, write() will use
       ""\n"", which yields different strings depending on the current
       runtime platform: \x0A on Unix; \x0D in MacPerl, \x0D\x0A on DOS.

       Otherwise, write() uses the value defined in _LineEnding, which
       would match the value filled in by read() if this object's data
       originally had been read from a file. So if you read a file and then
       later write it out, the line endings in the written file will match
       the format of original unless you override _LineEnding specifically.

       Since Data::CTable supports reading and writing all common endings,
       base your decision on line ending format during write() on the needs
       of other programs you might be using.

       For example: FileMaker Pro and Excel crash / hang if Unix line
       endings are used, so be sure to use the ending format that matches
       the needs of the other programs you plan to use.

       As a convenience, you may specify and retrieve the _LineEnding
       setting using the mnemonic symbols "mac", "dos" and "unix." These
       special values are converted to the string values shown in this
       chart:

                symbol   string value  chars  decimal     octal     control
               -------------------------------------------------------------
                 dos     "\x0D\x0A"    CR/LF   13,10    "\015\012"   ^M^J
                 mac     "\x0D"        CR      13       "\015"       ^M
                 unix    "\x0A"        LF      10       "\012"       ^J

       See the section LINE ENDINGS, below, for accessor methods and
       conversion utilities that help you get/set this parameter in either
       symbolic format or string format as you prefer.

   _FDelimiter ||= undef;
       _FDelimiter is the field delimiter between field names in the header
       row (if any) and also between fields in the body of the file. If
       undef, read() will try to guess whether it is tab ""\t"" or comma
       <",">, and set this parameter accordingly. If there is only one
       field in the file, then comma is assumed by read() and will be used
       by write().

       To guess the delimiter, the program looks for the first comma or tab
       character in the header row (if present) or in the first record.
       Whichever character is found first is assumed to be the delimiter.

       If you don't want the program to guess, or you have a data file
       format that uses a custom delimiter, specify the delimiter
       explicitly in the object or when calling read() or make a subclass
       that initializes this value differently. On write(), this will
       default to comma if it is empty or undef.

   _QuoteFields = undef unless exists
       _QuoteFields controls how field values are quoted by write() when
       writing the table to a delimited text file.

       An undef value (the default) means "auto" -- each field is checked
       individually and if it contains either the _FDelimiter character or
       a double-quote character, the field value will be surrounded by
       double-quotes as it is written to the file. This method is slower to
       write but faster to read, and may make the output easier for humans
       to read.

       A true value means always put double-quotes around every field
       value. This mode is faster to write but slower to read.

       A zero value means never to use double-quotes around field values
       and not to check for the need to use them. This method is the
       fastest to read and write. You may use it when you are certain that
       your data can't contain any special characters. However, if you're
       wrong, this mode will produce a corrupted file in the event that one
       of the fields does contain the active delimiter (such as comma or
       tab) or a quote.

   _HeaderRow = 1 unless exists
       _HeaderRow is a boolean that says whether to expect a header row in
       data files. The default is true: a header row is required. If false,
       _FieldList MUST be present before calling read() or an error will be
       generated. In this latter case, _FieldList will be assumed to give
       the correct names of the fields in the file, in order, before the
       file is read. In other words, the object expects that either a) it
       can get the field names from the file's header row or b) you will
       supply them before read() opens the file.

 Encoding of return characters within fields

   _ReturnMap = 1 unless exists
       _ReturnMap says that returns embedded in fields should be decoded on
       read() and encoded again on write(). The industry-standard encoding
       for embedded returns is ^K (ascii 11 -- but see next setting to
       change it). This defaults to true but can be turned off if you want
       data untouched by read(). This setting has no effect on data files
       where no fields contain embedded returns. However, it is vital to
       leave this option ON when writing any data file whose fields could
       contain embedded returns -- if you have such data and call write()
       with _ReturnMap turned off, the resulting file will be an invalid
       Merge/CSV file and might not be re-readable.

       When these fields are decoded on read(), encoded returns are
       converted to ""\n"" in memory, whatever its interpretation may be on
       the current platform (\x0A on Unix or DOS; \x0D on MacPerl).

       IMPORTANT NOTE: When these fields are encoded by write(), any
       occurrence of the current _LineEnding being used to write the file
       is searched and encoded FIRST, and THEN, any occurrence of "\n" is
       also searched and encoded. For example, if using mac line endings
       (^M) to write a file on a Unix machine, any ^M characters in fields
       will be encoded, and then any "\n" (^J) characters will ALSO be
       encoded. This may not be what you want, so be sure you know how your
       data is encoded in cases where your field values might contain any
       ^J and/or ^M characters.

       IMPORTANT NOTE: If you turn _ReturnMap off, fields with returns in
       them will still be double-quoted correctly. Some parsers of tab- or
       comma-delimited files are able to support reading such files.
       HOWEVER, the parser in this module's read() method DOES NOT
       currently support reading files in which a single field value
       appears to span multiple lines in the file. If you have a need to
       read such a file, you may need to write your own parser as a
       subclass of this module.

   _ReturnEncoding ||= "\x0B";
       This is the default encoding to assume when embedding return
       characters within fields. The industry standard is "\x0B" (ascii 11
       / octal \013 / ^K) so you should probably not ever change this
       setting.

       When fields are encoded on write(), ""\n"" is converted to this
       value. Note that different platforms use different ascii values for
       ""\n"", which is another good reason to leave the ReturnEncoding
       feature enabled when calling write().

       To summarize: this module likes to assume, and you should too, that
       returns in data files on disk are encoded as "\x0B", but once loaded
       into memory, they are encoded as the current platform's value of
       ""\n"".

   _MacRomanMap = undef unless exists
       Data::CTable assumes by default that you want field data in memory
       to be in the ISO 8859-1 character set (the standard for Latin 1
       Roman characters on Unix and Windows in the English and Western
       European languages -- and also the default encoding for HTML Web
       pages).

       _MacRomanMap controls the module's optional mapping of Roman
       characters from Mac format on disk to ISO format in memory when
       reading and writing data files. These settings are recognized:

               undef   ## Auto: Read/write Mac chars if using Mac line endings
               1       ## On:   Assume Mac char set in all fields
               0       ## Off:  Don't do any character mapping at all

       The default setting is undef, which enables "Auto" mode: files found
       to contain Mac line endings will be assumed to contain Mac
       upper-ASCII characters and will be mapped to ISO on read(); and
       files to be written with Mac line endings will mapped back from ISO
       to Mac format on write().

       If your data uses any non-Latin-1 character sets, or binary data, or
       you really want Mac upper-ASCII characters in memory, or you just
       don't want this module messing with your encodings, set this option
       to 0 (Off) or make a subclass that always sets it to 0.

       See also the clean() methods that can help you translate just the
       columns you want after reading a file or before writing it, which
       may be faster for you if only a few fields might contain high-ASCII
       characters.

   _FileName ||= undef;
       This is the name of the file that should be read from or WAS read
       from. (read() will set _FileName to the value it used to read the
       file, even if _FileName was only supplied as a named parameter.)

       This name will also be used, unless overridden, to re-write the file
       again, but with an optional extension added. (See next setting.)

   _WriteExtension = ".out" unless exists
       The _WriteExtension is provided so that CTable won't overwrite your
       input data file unless you tell it to.

       _WriteExtension will be added to the object's _FileName setting to
       create a new, related file name, before writing.... UNLESS _FileName
       is supplied as an direct or named parameter when calling write().

       In the latter case, write() uses the file name you supply and adds
       no extension, even if this would mean overwriting the original data
       file.

       To add _WriteExtension, write() places it prior to any existing
       final extension in the _FileName:

               _FileName             default file name used by write()
               --------------------------------------------------------------
               People.merge.txt      People.merge.out.txt
               People                People.out

       If you want to always overwrite the original file without having to
       supply _FileName each time, simply set _WriteExtension to undef in a
       subclass or in each instance.

       If _CacheOnWrite is true, then the _WriteExtension logic is applied
       first to arrive at the actual name of the file to be written, and
       then the _CacheExtension logic is applied to that name to arrive at
       the name of the cache file to be written.

 Sorting-related parameters

   _SortOrder ||= undef;
       _SortOrder is the list of fields which should be used as primary,
       secondary, etc. sort keys when sort() is called. Like other
       parameters, it may be initialized by a subclass, stored in the
       object, or provided as a named parameter on each call to sort().

       If _SortOrder is empty or undefined, then sort() sorts the records
       by record number (i.e. they are returned to their "natural" order).

   _SortSpecs ||= {};
       _SortSpecs is a hash of specifications for the SortType and
       SortDirection of fields on which sorting may be done. For any field
       missing a sort spec or the SortType or SortDirection components of
       its sort spec, the _DefaultSortType and _DefaultSortDirection
       settings will be used. So, for example, if all fields are of type
       String and you want them to sort Ascending, then you don't need to
       worry about _SortSpecs. You only need to provide specs for fields
       that don't take the default settings.

       _SortSpecs might look like this:

               {Age      => {SortType => 'Integer'},
                NameKey  => {SortType => 'Text', SortDirection => -1}}

   _SRoutines ||= {};
       _SRoutines is a hash mapping any new SortTypes invented by you to
       your custom subroutines for sorting that type of data. (See the
       section on sort routines, below, for a full discussion.)

 Sorting defaults

   _DefaultSortType ||= 'String';
       If you sort using a field with no sort spec supplied, or whose sort
       spec omits the SortType, it will get its SortType from this
       parameter.

       See the sections below on SORT TYPES and SORT ROUTINES.

   _DefaultSortDirection ||= 1;
       If you sort using a field with no sort spec supplied, or whose sort
       spec omits the SortDirection, it will get its SortDirection from
       this parameter.

       Legal sort directions are: 1 (Ascending) or -1 (Descending).

       See the section below on DEFAULT SORT DIRECTION.

 Miscellaneous parameters

   _ErrorMsg ||= "";
       This parameter is set by read() or write() methods that encounter an
       error (usually a parameter error or file-system error) that prevents
       them from completing. If those methods or any methods that call them
       return a false value indicating failure, then _ErrorMsg will contain
       a string explaining the problem. The message will also have been
       passed to the progress() method for possible console feedback.

   _Subset
       This parameter is set to 1 (true) by read() if the last call to
       read() brought in a subset of the fields available in the file; 0
       otherwise.

       The object uses this field internally so it knows to abandon any
       cache files that might not contain all requested fields upon read().

SUBCLASSING
   Most subclasses will override initialize() to set default values for the
   parameters of the parent class and then they may provide default values
   for other subclass-specific parameters. Then, the subclass's
   initialize() should call SUPER::initialize() to let the parent class(es)
   take care of the remaining ones.

   Every initialize() method should always allow for parameters to have
   already been provided by the $Params hash or template object. It should
   not overwrite any valid values that already exist.

   The following sample subclass changes the default setting of the
   _Progress parameter from undef to 1 and then overrides the
   progress_default() method to log all progress messages into a new
   "_ProgrLog" (progress log) parameter stored in the object.

           BEGIN
           {   ## Data::CTable::ProgressLogger: store messages in the object

               package Data::CTable::ProgressLogger;
               use vars qw(@ISA); @ISA=qw(Data::CTable);

               sub initialize       ## Add a new param; change one default
               {
                   my $this           = shift;
                   $this->{_Progress} = 1 unless exists($this->{_Progress});
                   $this->{_ProgrLog} ||= [];
                   $this->SUPER::initialize();
               }

               sub progress_default ## Log message to object's ProgMsgs list
               {
                   my $this            = shift;
                   my ($msg)           = @_;
                   chomp                                       $msg;
                   push @{$this->{_ProgrLog}}, localtime() . " $msg";

                   return(1);
               }

               sub show_log                 ## Use Dumper to spit out the log list
               {
                   my $this            = shift;
                   $this->dump($this->{_ProgrLog});
               }
           }

           ## Later...

           my $Table = Data::CTable::ProgressLogger->new("mydata.txt");
           # ... do stuff...
           $Table->write();
           $Table->show_log();

FIELD LIST
           ## Getting / setting the object's _FieldList

           $t->fieldlist()             ## Get _FieldList or fieldlist_all()
           $t->fieldlist_get()
           $t->fieldlist_hash()        ## Get fieldlist() as keys in a hash

           $t->fieldlist_all()         ## Get all fields (ignore _FieldList)

           $t->fieldlist($MyList)      ## Set field list (_FieldList param)
           $t->fieldlist_set($MyList)

           $t->fieldlist(0)            ## Remove field list (use default)
           $t->fieldlist_set()

           $t->fieldlist_force($MyList)## Set list; remove non-matching cols

           $t->fieldlist_truncate()    ## Just remove nonmatching cols

           $t->fieldlist_default()     ## Default field list (alpha-sorted)

           $t->fieldlist_add($MyName)    ## Append new name to custom list.
           $t->fieldlist_delete($MyName) ## Delete name from custom list.

   A CTable object can optionally have a custom field list. The custom
   field list can store both the ORDER of the fields (which otherwise would
   be unordered since they are stored as keys in a hash), and also can be a
   subset of the fields actually in the object, allowing you to temporarily
   ignore certain effectively-hidden fields for the benefit of certain
   operations. The custom field list can be changed or removed at any time.

   The custom field list is stored in the private _FieldList parameter.

   fieldlist() always returns a list (reference). The list is either the
   same list as _FieldList, if present, or it is the result of calling
   fieldlist_default(). In CTable, fieldlist_default() in turn calls
   fieldlist_all() -- hence fieldlist() would yield an auto-generated list
   of all fields in alphabetical order.

   fieldlist_all() can be called directly to get a list of all fields
   present regardless of the presence of a _FieldList parameter. The list
   is an alphabetical case-insensitively sorted list of all hash keys whose
   names do not begin with an underscore.

   You could override this method if you want a different behavior. Or, you
   could create your own custom field list by calling fieldlist_all() and
   removing fields or ordering them differently.

   To set a custom field list (in _FieldList), call fieldlist() or
   fieldlist_set() with a list (reference). The list must be a list of
   strings (field names) that do not begin with underscore. The object owns
   the list you supply.

   To remove a custom field list (and let the default be used), call
   fieldlist(0) or fieldlist_set() with no arguments (these will return the
   fieldlist that was deleted, if any).

   fieldlist_freeze() "freezes" the fieldlist in its current state. This is
   equivalent to the following:

           $t->fieldlist_set($t->fieldlist());

   ... which would force the fieldlist to $t->fieldlist_all() if and only
   if there is not already a custom _FieldList present.

   IMPORTANT NOTE ABOUT PARTIAL FIELD LISTS: When setting a field list, the
   object ensures that all fields (columns) mentioned in the list are
   present in the object -- it creates empty columns of the correct length
   as necessary. However, it does NOT delete any fields not mentioned in
   the field list. This allows you to manipulate the field list in order to
   have certain fields be temporarily ignored by all other methods, then
   alter, restore, or remove it (allow it to revert to default) and they
   will be effectively unhidden again. Some methods (such as cols(),
   write(), etc.) also allow you to specify a custom field list that will
   override any other list just during the execution of that method call
   but will not modify the object itself.

   Call fieldlist_force() to set the list AND have any non-listed fields
   also deleted at the same time (by calling fieldlist_truncate()
   internally). You can also just delete individual columns one-by-one, of
   course, using the column-manipulation methods and the custom fieldlist,
   if any, will be appropriately updated for you.

   fieldlist_truncate() deletes any fields found in the table but not
   currently present in _FieldList. A hash of the deleted columns is
   returned to the caller. If there is no _FieldList, then this method does
   nothing.

   fieldlist_default() just calls fieldlist_all() in this implementation,
   but could be changed in subclasses.

   fieldlist_add() is the internal method that adds a new field name to the
   custom field list (if present) and if the field name was not already on
   the list. It is called by other methods any time a new column is added
   to the table. Don't call it directly unless you know what you're doing
   because the corresponding column won't be created. (Instead, use col().)
   The field name is appended to the end of the existing custom field list.
   If there is no custom field list, nothing is done.

   fieldlist_delete() is the internal method that deletes a field name from
   the custom field list (if present). It is called by other methods when
   columns are deleted, but it does not actually delete the columns
   themselves, so use with caution: deleting a field from the custom field
   list effectively hides the field. This method has no effect, however, if
   there is no custom field list present. So don't call this method
   directly unless you know what you're doing.

DATA COLUMNS (FIELD DATA)
           ## Getting or setting data in entire columns

           $t->{$ColName}                ## Get a column you know exists
           $t->col($ColName)             ## Get a column or make empty one.
           $t->col_get($ColName)

           $t->col($ColName, $ListRef)   ## Set all of a column all at once.
           $t->col_set($ColName, $ListRef)
           $t->col_force($ColName, $ListRef) ## Add but don't check size or
                                             ##  add to custom field list

           $t->col_set($ColName, undef)  ## Delete a column completely
           $t->col_delete($ColName)

           $t->col_empty()            ## An empty col presized for table
           $t->col_empty(22)          ## An empty col of another length
           $t->col_empty($Col)        ## An empty col sized to match another

           $t->col_default()          ## Default if req. column not found.

           $t->col_exists($Field)     ## Check existence of column
           $t->col_active($Field)     ## Restrict check to fieldlist()

           $t->cols($ColList)         ## Get list of multiple named columns
           $t->cols_hash($ColList)    ## Get hash " " "

           $t->col_rename($Old => $New) ## Change name of columns
           $t->col_rename($Old1 => $New1, $Old2 => $New2) ## Change several

   A "column" is a field in the table and all its data. The column's field
   name is a key in the object itself, and may also optionally be listed in
   a custom field list if present. The column's data is the key's value in
   the hash and is an array ref of values presumed to be of the same data
   type (e. g. string, integer, etc.)

   Sometimes the terms "column" and "field" are used interchangeably in
   this documentation.

   If you already know that a column exists (because you got it from the
   fieldlist() method and you've not previously manipulated _FieldList
   directly but instead carefully used the method calls available for
   that), then you can safely get the column by just looking it up in the
   object itself.

   The col() method does the same thing, but forces the column to spring
   into existence if it did not already (which can also have the
   potentially unwanted side-effect of hiding coding errors in which you
   retreive mis-named columns: so beware). Columns brought into existence
   this way will automatically be pre-sized (i.e. they will will be created
   and set to whatever col_default() returns).

   The col() or col_set() methods can also be used to set a column. When
   the column is set, the list you pass is automatically sized (lengthened
   or truncated) to match the current length of the table. If this is not
   what you want, then call col_force() which will not check whether the
   new column matches the size of the others.

   No matter how you set it, the object now "owns" the list you gave it.

   As a convenience, col(), col_set() and col_force() return the column
   that was set. They silently discard any previous column.

   All three methods of column setting will append the column to the custom
   field list if one is present and the column name is not already listed
   there (by calling fieldlist_add()). They will also call the extend()
   method to ensure all columns have the same length (either others will be
   extended to match the length of the new one, or the new one will be
   extended to match the length of the others).

   col_delete() deletes a column.

   col_empty() returns an anonymous list reference that is pre-sized to the
   length of the table (by default). You could use it to get an empty
   column that you intend to fill up and then later insert into the table
   or use to hold the results of an operation on other columns. If you want
   a different length, specify it as a number or as an array ref whose
   length should be matched.

   col_default() is the internal method that implements the "springing into
   existence" of missing columns. Currently it just calls col_empty().
   Other subclasses might want to have it return undef or a string like
   "NO_SUCH_COLUMN" in order to help track programming errors where
   nonexistent columns are requested.

   cols($FieldList) returns an ordered list of the requested column names.
   If no list is given, then fieldlist() is used.

   cols_hash($FieldList) does the same as cols(), but the result is a hash
   whose keys are the field names and whose values are the columns -- much
   like the original object itself, but not blessed into the class. The
   resulting hash, however, could be used as the prototype for a new
   Data::CTable object (by calling the new() method). However, be warned
   that both objects will think they "own" the resulting shared so be
   careful what you do..... which brings us to this:

   IMPORTANT NOTE ABOUT GETTING COLUMNS: The columns you retrieve from a
   table are still "owned" by the table object as long as it lives. If you
   modify them, you are modifying the table's data. If you change their
   length, then you may be invalidating the table's own expectations that
   all its columns have the same length. So beware.

   Just make yourself a copy of the data if that isn't what you want. For
   example, instead of this:

           my $Foo =    $Table->col('Foo');   ## Reference to actual column

   Do this:

           my $Foo = [@{$Table->col('Foo')}]; ## Shallow copy of the column

CLEANUP AND VALIDATION
           ## Performing your own cleanups or validations

           $t->clean($Sub)           ## Clean with custom subroutine
           $t->clean($Sub, $Fields)  ## Clean specified columns only

           ## Cleaning whitespace

           $t->clean_ws()        ## Clean whitespace in fieldlist() cols
           $t->clean_ws($Fields) ## Clean whitespace in specified cols

           ## Cleaning methods that map character sets

           $t->clean_mac_to_iso8859()
           $t->clean_mac_to_iso8859($Fields)

           $t->clean_iso8859_to_mac()
           $t->clean_iso8859_to_mac($Fields)

           ## Character mapping utilities (not methods)

           use Data::CTable qw(
                               ISORoman8859_1ToMacRoman
                               MacRomanToISORoman8859_1

                               ISORoman8859_1ToMacRoman_clean
                               MacRomanToISORoman8859_1_clean
                               );

           &ISORoman8859_1ToMacRoman(\ $Str)  ## Pass pointer to buffer
           &MacRomanToISORoman8859_1(\ $Str)  ## Pass pointer to buffer

           &ISORoman8859_1ToMacRoman_clean()  ## Operates on $_
           &MacRomanToISORoman8859_1_clean()  ## Operates on $_

   One of the most important things you can do with your data once it's
   been placed in a table in Perl is to use the power of Perl to scrub it
   like crazy.

   The built-in clean_ws() method applies a standard white-space cleanup to
   selected records in every field in the fieldlist() or other list of
   fields you optionally supply (such as fieldlist_all()).

   It does the following cleanups that are deemed correct for the majority
   of data out there:

           - Remove all leading whitespace, including returns (\n)
           - Remove all trailing whitespace, including returns (\n)
           - Convert runs of spaces to a single space
           - Convert empty string values back to undef to save space

   Of course, depending on your data, clean_ws() might just be the first
   thing you do in your cleanup pass. There might be many more cleanups
   you'd like to apply.

   clean() is like clean_ws() except you supply as the first argument your
   own cleaning subroutine (code reference). It should do its work by
   modifying $_.

   Both clean_ws() and clean() apply cleaning ONLY to selected records. If
   this isn't what you want, then select_all() before cleaning.

   Since a cleanup subroutine can do ANY modifications to a field that it
   likes, you can imagine some cleanup routines that also supply default
   values and do other validations.

   For example, a cleanup routine could convert every value in each field
   to an integer, or apply minimum or maximum numerical limits:

           sub {$_ =     int($_)      }
           sub {$_ = max(int($_), 0)  }
           sub {$_ = min(int($_), 200)}

   Or your cleanup routine could use regular expressions to do
   capitalizations or other regularizations of data:

           sub Capitalize {/\b([a-z])([a-z]+)\b)/\U$1\E$2/g}

           $t->clean(\ &Capitalize , ['FirstName', 'LastName']);
           $t->clean(\ &PhoneFormat, ['Phone', 'Fax'         ]);
           $t->clean(\ &LegalUSZip,  ['HomeZip', 'WorkZip'   ]);

   ... and so on. Cleanups are easy to write and quick and easy to apply
   with Data::CTable. Do them early! Do them often!

 Hints for writing cleanup routines

   If your cleanup routine may be used to clean up fields that could be
   empty/undef and empty/undef is a legal value, it should not touch any
   undef values (unintentionally converting them to strings).

   Finally, instead of setting any values to the empty string, it should
   set them to undef instead. This includes any values it might have left
   empty during cleanup. (Using undef instead of empty string to represent
   empty values is one way that Data::CTable likes to save memory in tables
   that may have lots of those.)

   For an example of a well-behaved cleanup routine, consider the following
   implementation of the builtin CleanWhitespace behavior:

           sub CleanWhitespace
           {
               return unless defined;    ## Empty/undef values stay that way
               s/ \s+$//sx;              ## Remove trailing whitespace
               s/^\s+ //sx;              ## Remove leading whitespace
               s/ +/ /g;                 ## Runs of spaces to single space
               $_ = undef unless length; ## (Newly?) empty strings to undef
           }

 Roman character set mapping

   The character set mapping cleanup routines can be used to convert
   upper-ASCII characters bidirectionally between two popular Roman
   Character sets -- Mac Roman 1 and ISO 8859-1 (also sometimes called ISO
   Latin 1) -- i.e. the Western European Roman character sets.

   By default, read() converts all incoming data fields in data files with
   Mac line endings to ISO format when reading in. Conversely, write() does
   the reverse mapping (ISO to Mac) when writing a file with Mac line
   endings.

   However, you may wish to turn off these default behaviors and instead
   apply the mappings manually, possibly just to certain fields.

   For example, if a table contains fields with non-Roman character sets,
   you would definitely not want to apply these mappings, and instead might
   want to apply some different ones that you create yourself.

 Utility routines for character mapping

   This module can optionally export four utility routines for mapping
   character Latin 1 character sets. Always be sure to map the correct
   direction -- otherwise you'll end up with garbage! Be careful to only
   pass Western Roman strings -- not double-byte strings or strings encoded
   in any single-byte Eastern European Roman or non-Roman character set.

           &ISORoman8859_1ToMacRoman(\ $Str)  ## Pass pointer to buffer
           &MacRomanToISORoman8859_1(\ $Str)  ## Pass pointer to buffer

   These routines translate characters whose values are 128-255 from one
   Western Roman encoding to another. The argument is a string buffer of
   any size passed by reference.

   The functions return a count of the number of characters that were
   mapped (zero or undef if none were).

           &ISORoman8859_1ToMacRoman_clean()  ## Operates on $_
           &MacRomanToISORoman8859_1_clean()  ## Operates on $_

   These routines are variants of the above, but they're versions that are
   compatible with clean() -- they operate on $_ and will take care to
   leave undefined values undefined. They do not have return values.

 More advanced cleaning and validation

   Unfortunately, clean() only lets you operate on a single field value at
   a time -- and there's no way to know the record number or other useful
   information inside the cleaning routine.

   For really powerful cleaning and validation involving access to all
   fields of a record as well as record numbers, see the discussion of the
   calc() method and other methods for doing complex field calculations in
   the next section.

CALCULATIONS USING calc()
           ## Calculate a new field's values based on two others

           $t->calc($Sub)              ## Run $Sub for each row, with
                                       ##  fields bound to local vars

           $t->calc($Sub,  $Sel)           ## Use these row nums
           $t->calc($Sub, undef, $Fields)  ## Use only these fields
           $t->calc($Sub,  $Sel, $Fields)  ## Use custom rows, fields

           my $Col = $t->calc($Sub)    ## Gather return vals in vector

           ## Example 1: Overwrite values in an existing column.

           $t->calc(sub{no strict 'vars'; $Size = (stat($Path))[7]});

           ## Example 2: Create empty column; fill fields 1 by 1

           $t->col('PersonID');
           $t->calc(sub{no strict 'vars'; $PersonID = "$Last$First"});

           ## Example 3: Calculate values; put into to table if desired

           $PersonID = $t->calc(sub{no strict 'vars'; "$Last$First"});
           $t->sel('PersonID', $PersonID);

           ## Example 4: Using fully-qualified variable names

           $t->calc(sub{$main::PersonID = "$main::Last$main::First"});

   calc() runs your custom calculation subroutine $Sub once for every row
   in the current selection() or other list of row numbers that you specify
   in the optional $Sel argument.

   This lets you apply a complex calculation to every record in a table in
   a single statement, storing the results in one or more columns, or
   retrieving them as a list.

   Your custom subroutine may refer to the value in any field in the
   current row by using a global variable with the field's name:

   For example, if the table has fields First, Last, and Age, then $Sub may
   use, modify, and set the variables $First, $Last, $Age. (Also known as
   $main::First, $main::Last, $main::Age).

   Modifying any of these specially-bound variables actually modifies the
   data in the correct record and field within the table.

   By default, the fields available to $Sub are all fields in the table.
   calc() must bind all the field names for you for each row, which can be
   time-consuming for tables with very large numbers of fields.

   You can speed up the operation of calc() by listing only the fields your
   $Sub needs in the optional parameter $Fields. Any field names you don't
   mention won't be available to $Sub. Conversely, calc() will run faster
   because it can bind only the fields you actually need.

   If you include non-existent fields in your custom $Fields list, calc()
   creates them for you before $Sub runs the first time. Then your $Sub can
   store field values into the new column, referring to it by name.

   Variables in $Sub are in the "main" package. So you should set $Sub to
   use pacakge "main" in case the rest of your code is not in "main".

   Similarly, if you "use strict", Perl will complain about global
   variables in $Sub. So you may need to assert "no strict 'vars'".

           {   package Foo; use strict;

               $t = ...;
               $t->calc(sub {package main; no strict 'vars';
                             $Age = int($Age)});
           }

           ## Or this:

           {   package Foo;  use strict;

               $t = ...;
               {   package main; no strict 'vars';
                   my $Sub = sub {$Age = int($Age)};
               }
               $t->calc($Sub);
           }

   You may be able to get around both problems more easily by prefixing
   each variable reference in $Sub with "main::". This takes care of the
   package name issue and bypasses "use strict" at the same time, at the
   slight cost of making the calculation itself a bit harder to read.

           $t->calc(sub {$main::Age = int($main::Age)}); ## OK in any package

   In addition to the field names, the following three values are defined
   during each invocation of $Sub:

           $_r ($main::_r) -- the row number in the entire table
           $_s ($main::_s) -- the item number in selection or $Recs
           $_t ($main::_t) -- the table object itself

   You could use these values to print diagnostic information or to access
   any of the data, parameters, or methods of the table itself from within
   $Sub. Or you could even calculate field values using $_r or $_s.

   For example, after searching & sorting, you could make a field which
   preserves the resulting sort order for future reference:

           $t->col('Ranking');      ## Create the empty column first.
           $t->calc(sub{$main::Ranking = $main::_s});

   This last example is equivalent to:

           $t->sel(Ranking => [0 .. $#{$t->selection()}]); ## See sel() below

"MANUAL" CALCULATIONS
   calc() (see previous secion) is the briefer, more elegant way to do
   batch calculations on entire columns in a table, but it can be slightly
   slower than doing the calculations yourself.

   If you have extremely large tables, and you notice the processing time
   for your calculations taking more than a second, you might want to
   rewrite your calculations to use the more efficient techniques shown
   here.

   You will often need to create new calculated columns based on one or
   more existing ones, and then either insert the columns back in the
   tables or use them for further calculations or indexing.

   Examples 1a and 1b create a new field 'NameOK' containing either the
   string "OK" or undef (empty) depending on whether the field 'Name' is
   empty. Just use map() to iterate over the existing values in the other
   column, binding $_ to each value in turn.

           ### Example 1a: Calculation based on one other column

           ## Retrieve column
           my $Name    = $t->col('Name');

           ## Make new column
           my $NameOK  = [map {!!length && 'OK'} @$Name];

           ## Insert column back into table:
           $t->col(NameOK => $NameOK);

           ### Example 1b: Same calculation, in a single statement:

           $t->col(NameOK => [map {!!length && 'OK'} @{$t->col('Name')}]);

   In order to iterate over MULTIPLE columns at once, you need a list of
   the row numbers generated by $t->all() so you can index the two columns
   in tandem. Then, you use map to bind $_ to each row number, and then use
   the expression $t->col($ColName)->[$_] to retreive each value.

   Examples 2a and 2b demonstrate this method. They create a new field
   'FullName' which is a string joining the values in the 'First' and
   'Last' columns with a space between.

           ### Example 2a: Calculation based on multiple columns

           ## Retrieve columns
           my $First = $t->col('First');
           my $Last  = $t->col('Last' );

           ## Retreive row nums
           my $Nums  = $t->all();

           ## Calculate a new column based on two others
           my $Full  = [map {"$First->[$_] $Last->[$_]"} @$Nums];

           ## Add new column to the table
           $t->col(FullName => $Full);

           ### Example 2b: Same calculation, in a single statement:

           $t->col(FullName =>
                   [map {"$t->col('First')->[$_] t->col('Last')->[$_]"}
                    @{$t->all()}]);

   In examples 1 and 2, you create entirely new columns and then add or
   replace them in the table.

   Using the approach in Examples 3a and 3b, you can assign calculated
   results directly into each value of an existing column as you go.

           ## Example 3a: Calculate by assigning directly into fields...

           my $A = $t->col->('A'); ## This column will be modified
           my $B = $t->col->('B');
           my $C = $t->col->('C');

           foreach @($t->all()) {$A->[$_] = $B->[$_] + $C->[$_];}

           ## Example 3b: Same calculation, in a single statement:

           foreach @($t->all()) {($t->col('A')->[$_] =
                                  $t->col('B')->[$_] +
                                  $t->col('C')->[$_])};

   Before writing your code, think about which calculation paradigms best
   suit your needs and your data set.

   Just as Perl Hackers know: There's More Than One Way To Do It!

INDEXES
           ## Make indexes of columns or just selected data in columns

           my $Index1 = $t->index_all($Key);  ## entire column
           my $Index2 = $t->index_sel($Key);  ## selected data only

           ## Make hashes of 2 columns or just selected data in columns

           my $Index1 = $t->hash_all($KeyFld, $ValFld);  ## entire column
           my $Index2 = $t->hash_sel($KeyFld, $ValFld);  ## selected data

   index_all() creates and returns a hash (reference) that maps keys found
   in the column called $Key to corresponding record numbers.

   Ideally, values in $Key would be unique (that's up to you).

   If any values in $Key are NOT unique, then later values (higher record
   numbers) will be ignored.

   index_sel() creates and returns a hash (ref) that maps keys found in the
   SELECTED RECORDS of column $Key to corresponding record numbers.

   Any keys in unselected records are ignored. Otherwise, the behavior is
   equivalent to index_all().

   hash_all() and hash_sel() are similar, except they create and return
   hashes whose keys are taken from column $KeyFld, but whose values are
   from $ValFld in the corresponding records.

   So, for example, imagine you have a tab-delimited file on disk with just
   a single tab per line (2 fields) and no header row. The entries on the
   left side of the tab on each line are keys and the right side are
   values. You could convert that file into a hash in memory like this:

           my $t = Data::CTable->new({_HeaderRow=>0, _FieldList=>[qw(F1 F2)]},
                                     "DeptLookup.txt");

           my $DeptLookup = $t->hash_all(qw(F1 F2));

 Reverse indexes

   If you'd like an index mapping record number to key, just get
   $t->col($Key). That's what the data columns in Data::CTable are.

DATA ROWS (RECORDS)
           ## Getting or setting rows / records

           $t->row($Num)             ## Get a row or make empty one.
           $t->row_get($Num)

           $t->row($Num, $HashRef)   ## Set all of a row all at once.
           $t->row_set($Num, $HashRef)

           $t->row_set($Num, undef)  ## Delete a row completely
           $t->row_delete($Num)
           $t->row_delete($Beg, $End)## Delete a range of rows

           $t->row_move($Old, $New)   ## Move a row to before $New

           $t->row_empty()            ## An empty hash
           $t->row_exists($Num)       ## True if $Num < $t->length()

           $t->rows($RowList)         ## Get list of multiple row nums

           $t->row_list($Num)          ## Get row vals as a list
           $t->row_list($Num, $Fields) ## Get row vals: specified fields

           $t->row_list_set($Num, undef, $Vals)   ## Set row vals as a list
           $t->row_list_set($Num, $Fields, $Vals) ## Set row vals as a list
           $t->row_list_set($Num, $Fields)        ## Set vals to empty/undef

   Usually, when working with Data::CTable objects, you are operating on
   entire columns or tables at a time (after all: any transformation you do
   on one record you almost always want to do on all records or all
   selected ones).

   You should very rarely need to access data by retrieving rows or setting
   rows, moving them around individually, and so on. (It's much cleaner,
   and much more efficient to manipulate the selection() (list of selected
   row numbers) instead -- just delete a row number from the selection, for
   example, and then for most operations it's almost as if the row is gone
   from the table, except the data is really still there.)

   However, if on rare occasions you really do need direct row operations,
   you're reading the right section.

   A row is generally accessed as a hash. The hash you provide or get back
   is not saved by the object in any way. Data values are always copied in
   or out of it, so you always "own" the hash.

   Rows are specified by $Num -- the row number with in the unsorted
   columns (the raw data in the table). These numbers are just array
   indices into the data columns, and so their legal range is:

           [0 .. ($t->length() - 1)]     ##   (Zero-based row numbering.)

   The row hash (or "record") has keys that are field names and values that
   are copies of the scalar values stored in the data columns within the
   table.

   row() always copies only the fields in fieldlist(), except for
   row_list() which allows you to specify an optional $Fields parameter
   which can override the current fieldlist().

   If the fieldlist happens to be a subset of all fields, but you really
   want to get all fields in your record, then call fieldlist_set(0) first
   to permanently or temporarily delete it.

   row() and row_get() always return a hash.

   row($Num, $Hash), row_set() take a hash and set just the fields you
   specify in the hash (in the given row of course). Any non-existent field
   names in the hash are created, so be careful.

   In fact, in general with either getting or setting rows, any
   non-existent fields mentioned will be created for you (by internally
   calling col()). So you could build a whole table of 100 rows by starting
   with an empty, new, table and setting row 99 from a hash that gives the
   field names.

   Setting a row number higher than any existing row number with row(),
   row_set() or row_force() will automatically set the new length of the
   entire table to match (extending all the columns with empty rows as
   necessary).

   IMPORTANT: IF YOU SIMPLY MUST ADD ROWS SEQUENTIALLY, do not let the
   table auto-extend by one with each row you set. This is slow and gets
   rapidly slower if there's lots of data because the arrays holding the
   data columns will keep getting reallocated on every insert. Instead,
   first pre-extend the table to your highest row number by calling
   length($Len), and then set your rows. Or easier: if convenient just set
   your rows starting with the highest-numbered one first. If you don't
   know how many you'll have, guess or estimate and pre-extend to the
   estimated number and then cut back later. This will be faster than
   extending all columns by one each time.

   row_delete() removes a row or range of rows completely from the table.
   Any rows above the deleted ones will move down and the table's length()
   will decrease. If the data columns are very large, this could be a bit
   slow because a lot of data could be moved around. The low and high row
   numbers will be limited for you to 0 and length() - 1, respectively.
   Null ranges are OK and are silently ignored. The range is inclusive, so
   to delete just row 99, call row_delete(99) or row_delete(99,99).

   EFFICIENCY NOTE: Don't call row_delete() to remove lots of individual
   rows. Instead, select those row numbers by setting the selection (if not
   already selected), and then invert the selection using
   selection_invert(), so the undesired rows are deselected, and then use
   the cull() method to rewrite the entire table at once. The deselected
   rows will be omitted very efficiently this way.

   row_move() moves a row from its $Old row number to the position before
   the row currently in row $New (specify $New = length() to move the row
   to the end). Again, in shuffling data in columns, lots of data could get
   moved around by this operation, so expect it to be slow. If as with
   row_delete(), if you will be doing several moves, consider building an
   appropriate selection() first, and then using cull() instead.

   Using row_delete() and row_move() to shift records around changes the
   record numbers of the affected records and many others in the table. The
   record numbers in the custom selection, if any, are updated to reflect
   these changes, so the records that were selected before will still be
   selected after the move (except those that were deleted of course). If
   you had a private copy of the selection, your copy will likely become
   outdated after these operations. You should get it again by calling
   selection().

   row_empty() returns a hash whose keys are the entries in fieldlist() and
   whose values are undef. (You could use it to fill in values before
   calling row_set()). Note: in this class, row_empty() does exactly the
   same thing as fieldlist_hash() when the latter is called with no
   arguments.

   row_exists() returns true if "(($Num >= 0) && ($Num < $t->length()))".

   rows() calls row() for each row num in a list and returns a list of the
   resulting hashes.

   row_list() gets row values as a list instead of a hash. They appear in
   the order specified in fieldlist() unless you supply an optional $Fields
   parameter listing the fields you want to get.

   row_list_set() sets row values as a list instead of a hash. Pass your
   own $Fields list or undef and fieldlist() will be used. $Values should
   be a list with the same number of values as fields expected; any
   shortage will result in undef/empty values being set.

ROW / RECORD COUNT (TABLE LENGTH)
           ## Getting or setting table length

           $t->length()        ## Get length
           $t->length_get()

           $t->length(22)      ## Set length (truncate or pre-extend)
           $t->length_set(22)

           $t->extend()        ## Set length of all columns to match longest

   The length* methods assume the table already has columns of equal
   length. So the length of the table is the length of any field taken at
   random. We choose the first one in the field list.

   Setting the length will truncate or pre-extend every column in the table
   to a given length as required.

   (Pre-extending means setting each column's length via $# so that it has
   the correct number of entries already allocated (and filled with undef)
   so that operations that fill up the table can be done much more quickly
   than with push().

   However, if a new column has been added directly, or a table has been
   constructed out of columns whose length may not initially match, the
   extend() method may be (should be) called to inspect all columns and
   extend them all to match the longest one. Note that extend() operates on
   all fields in the object, ignoring the custom _FieldList if any.

   The length of a table with no columns is zero.

SELECTIONS
           ## Getting or setting the custom selection list itself (_Selection)

           $t->selection()               ## Get sel if any; else all()
           $t->selection_get()

           $t->selection($List)          ## Set sel (list of rec nums)
           $t->selection_set($List)

           $t->selection(0)              ## Remove sel (select all)
           $t->selection_set(undef)
           $t->selection_delete()
           $t->select_all()

           $t->selection_inverse()       ## Get inverse copy of selection
           $t->select_inverse()          ## Invert the selection

           $t->selection_validate()      ## Remove invalid #s from sel

           ## List of all rec nums present (regardless of selection)

           $t->all()

           ## Getting or setting just selected fields in columns
           ## (as contrasted with col() and friends).

           $t->sel($ColName)             ## Get col but only records in sel
           $t->sel_get($ColName)

           $t->sel($ColName, $ListRef)   ## Set selected fields in col...
           $t->sel_set($ColName, $ListRef) ##... in selection order

           $t->sel_set($ColName)         ## Set selected fields to undef
           $t->sel_clear($ColName)

           $t->sels($ColList)            ## Like cols, but selected fields
           $t->sels_hash($ColList)       ## " "   cols_hash()... " " " "

           ## Finding out size of selection (number of rows)

           $t->sel_len()                 ## Get number of selected rows.

   A selection is an ordered list of record numbers. The record numbers in
   the selection may be a subset of available records. Furthermore, they
   may be in non-record-number order, indicating that the records have been
   sorted.

   Record numbers are numeric array indices into the columns in the table.
   It is an error for any selection list to contain an index less than zero
   or greater than (length() - 1), so if you set a selection explicitly, be
   careful.

   Any selection list you get or set belongs to the object. Be careful of
   modifying its contents.

   The custom selection, if any, is stored internally in the _Selection
   parameter. If this parameter is absent, the selection defaults to all()
   -- i.e. a list of all record numbers, in order: [0..($this->length() -
   1)] (which becomes [] if length() is 0).

   REMEMBER: length() is one-based, but record numbers are zero-based.

   Removing the selection (that is, removing the LIST itself of which
   records are selected), is the same as selecting all records.
   consequently, selection(0), selection_delete(), and select_all() are all
   synonymous.

   selection_validate() removes any entries from the current _Selection
   list (if any) that are not valid record numbers -- i.e. it removes any
   record whose integer value is < 0 or greater than length() - 1. This
   routine is mainly used by other methods that might delete records, such
   as length_set().

   Getting or setting just selected data from columns

   Sometimes, you don't want to get/set entire columns, you instead want to
   get or set data in just the selected fields in a column.

   The sel(), sel_get(), sel_set(), sels() and sels_hash() methods are
   analagous to the corresponding col(), ... cols_hash() methods except in
   these two ways:

   - the 'sels' variants get or set just selected data, as determined by
   the current selection(), which gives an ordered list of the selected /
   sorted records.

   - the 'sels' variants all make COPIES of the data you request or supply
   -- the data is copied out of or into the correspnding column. So, you
   "own" any vector you pass or receive in reply.

   So, for example, imagine you have just set selection() to only list
   record numbers where the LastName field is not empty. Then you have
   called sort() to sort those record numbers by the LastName field. You
   could then call $t->sel('LastName') to get a sorted list of all
   non-empty last names.

   It might be helpful to think of "sel" as short for "selected". So
   $t->sel('LastName') would mean "get the selected field values from the
   LastName field".

SEARCHING / SELECTING RECORDS
           ## Modifying the table's custom selection (_Selection)

           $t->select_all()      ## Set _Selection = $t->all() or undef
           $t->select_none()     ## Set _Selection = []
           $t->select_inverse()  ## Invert the curr. sel. (and get it)

           ## Specific searches: "the select() methods"

           $t->select($Field1=>$Sub1, ## Del nonmatching recs from sel.
                      $Field2=>$Sub2, ## i.e. narrow sel. to match
                      ...);

           $t->omit  ($Field1=>$Sub1, ## Del matching recs from sel.
                      $Field2=>$Sub2,
                      ...);

           $t->add   ($Field1=>$Sub1, ## Add matching recs to sel.
                      $Field2=>$Sub2,
                      ...);

           $t->but   ($Field1=>$Sub1, ## Add nonmatching recs to sel.
                      $Field2=>$Sub2,
                      ...);

           ## Getting useful lists of record numbers...

           $t->all()                  ## Get "full" sel. (all record #s)
           $t->selection()            ## Get current selection
           $t->selection_inverse()    ## Get inverse copy of curr. sel.

           ## Example 1: Refine a selection by narrowing down...

           $t->select_all()
           $t->select(Field1 => sub {$_});
           $t->select(Field2 => sub {$_});
           $t->select(Field3 => sub {$_});

           ## Example 2: Manually refine and set the selection...

           $Sel = [grep {$t->col($Field1)->[$_]} @{$t->all      ()}];
           $Sel = [grep {$t->col($Field2)->[$_]} @$Sel];
           $Sel = [grep {$t->col($Field3)->[$_]} @$Sel];
           $t->selection($Sel);    ## Set the selection when done.

           ## Example 3: Complex manual search using calculated value

           my $A = $t->col('A');
           my $B = $t->col('B');
           my $S = [grep
                    {my $X = $A->[$_] + $B->[$_]; ($X > 100 && $X < 200);}
                    @{$t->all()}]; ## Or could start with $t->selection().
           $t->selection($S);      ## Set the selection when done.

           ## Example 4: Refine a selection by building up...

           $t->select_none()
           $t->add(Field1 => sub {$_});
           $t->add(Field2 => sub {$_});
           $t->add(Field3 => sub {$_});

           ## Example 5: Combining the select() methods to build a query...

           $t->select_all()
           $t->select(Status  => sub {/prime/i   });
           $t->omit  (DueDate => sub {$_ > $Today});
           $t->add   (Force   => sub {$_         });

   select() and its friends omit(), add(), and but(), known collectively as
   "the select() methods," all work similarly: they take a series of one or
   more pairs indicating matches to be done, where each match is specified
   as (FieldName => Subroutine).

   In addition to the field names already present in the table, the
   FieldName in any Spec may also be one of these two special
   pseudo-fields:

   _RecNum
       the record number of the record being compared

   _SelNum
       the numerical position of the record being compared within the
       previous selection (only usable with select() and omit() since add()
       and but() by definition operate on non-selected records).

   For example:

           ## Match 2nd 100 rec numbers
           $t->select(_RecNum => sub {$_ >= 100 && $_ <= 199});

           ## Match 2nd 100 currently selected/sorted items
           $t->select(_SelNum => sub {$_ >= 100 && $_ <= 199});

   Be careful when using _SelNum in a search. In the above _SelNum search
   example, since the selection itself will be modified by select(), the
   items that were formerly selection items 100 - 199 will now be _SelNum 0
   - 99 in the new selection.

   The Subroutine is an anonymous grep-style predicate that operates on $_
   and should return true/false to indicate a match with an element of the
   field FieldName.

   The order of multiple matches in a single method call is significant
   only in that the searches can be faster if the field that will match the
   fewest records is listed first.

   A given FieldName may be listed in the specs more than once if it has
   multiple search criteria that you prefer to execute as multiple
   subroutines (though it would be more efficient on very large tables to
   combine their logic into one subroutine joined with "&&").

   Each field match will be applied (with an implied AND joining them) to
   determine whether the record itself matches. Then, based on whether the
   record itself matches, it will either be added or deleted from the
   selection based on which method is being called:

           method...  operates on...     action....
           ------------------------------------------------------------------
           select()   selected records   Keep only recs that DO     match
           omit()     selected records   Keep only recs that DO NOT match
           add()      non-selected recs  Add       recs that DO     match
           but()      non-selected recs  Add       recs that DO NOT match

   Here's how to think about what's going on:

           methods... think...
           ------------------------------------------------------------------
           select()   "SELECT things matching this"...
           omit()     "... then OMIT those matching this."

           select()   "SELECT things matching this"...
           add()      "... and ADD any others matching this."

           select()   "SELECT things matching this"...
           but()      "... and add any others BUT those matching this."

   select() and omit() both NARROW the selection.

   add() and but() both INCREASE the selection.

   IMPORTANT: You DO NOT need to use these select() routines to work with
   selections. It may be much easier for you to clarify your logic, or more
   efficient to express your search, using a single grep or series of grep
   operations as in Examples 2 or 3 above.

   Building the selection manually is required if you want to filter based
   on any COMPLEX RELATIONSHIPS BETWEEN FIELDS. For example, if you want to
   add two fields and match or reject the record based on the sum of the
   fields.

   In Example 3 above, we add the values in fields "A" and "B" and then
   match the record only if the SUM is between 100 and 199. By grepping to
   produce a subset of @{$t->all()}, you end up with a Selection -- a list
   of record numbers you want "selected". Then you call $t->selection() to
   put the selection you built into the object.

   If you had instead wanted to narrow an existing selection in the above
   example, you would start with $t->selection() (which defaults to
   $t->all()) instead of starting with $t->all().

   Each of the select() methods returns $this->selection() as a
   convenience.

 The effects of modifying a sorted selection

   Generally, you should sort AFTER finding, and you should not generally
   rely on sort order after doing a find. But in case you want to know, the
   following chart explains what happens to the sort order after the
   various select() commands are called (at least in the current
   implementation, which may change without notice):

           method... effect on an existing sort order...
           ------------------------------------------------------------------
           select()  relative sort order is preserved (stay sorted)
           omit()    all selected recs restored to "natural" order (unsorted)
           add()     orig. recs preserved; new recs appended: "natural" order
           but()     orig. recs preserved; new recs appended: "natural" order

   In other words, you could sort() first and then call select() to narrow
   down the selection repeatedly without disrupting the sort order.
   However, any of the other methods will disrupt the sort order and you
   would need to re-sort. The preservation of order when using select(),
   and other sort order effects, are likely but not guaranteed to be
   preserved in future implementations.

 Hints about Boolean logic

   Consider the following example and the alternative below it. You might
   initially think these are equivalent, but they're not:

           ## Case 1:

           my $Sel = $t->add(Force  => sub {$_ == 1      });
           my $Sel = $t->add(Status => sub {$_ eq 'Prime'});

           ## Case 2:

           my $Sel = $t->add(Force  => sub {$_ == 1      },
                             Status => sub {$_ eq 'Prime'});

   Case 1 extends the selection by adding all records where Force == 1, and
   then extends it again by adding all additional records where Status eq
   'Prime'.

   Case 2 adds only those records where: Force == 1 AND ALSO, IN THE SAME
   RECORD, Status eq 'Prime'.

   One final note about logic. This is not SQL and these select() etc.
   routines are not meant to replace the full power of a programming
   language.

   If you want full Boolean expressions, use the power of Perl to form your
   own arbitrarily complex query using grep as in Example 3 above.

   Writing your own grep is also almost always faster than chaining the
   builtin select() methods or using multiple Field / Sub specifications,
   so keep that in mind when working with extremely large data sets.

   With tables of only a few thousand records or so, you probably won't
   notice the difference in efficiency.

SORTING
           ## Sort the current table's _Selection

           $t->sort()                       ## Use existing/default params
           $t->sort([qw(Last First Phone)]) ## Specify _SortOrder (fields)
           $t->sort(                        ## Named-parameter call:
                    _SortOrder => [...],    ##  override sort-related params.
                    _Selection => [...],    ##  (See param lists above).
                    _SortSpecs => {...},
                    _SRoutines => {...},
                    _DefaultSortType=>'Integer',
                    _DefaultSortDirection=>-1,
                    );

   The sort() method modifies the _Selection (creating one with all records
   if it was missing, undef, or not supplied by caller) so that the record
   numbers listed there are sorted according to the criteria implied by
   _SortOrder, _SortSpecs, _SRoutines, etc.

   For example, before sorting, a table's "natural" order might be:

           Rec# First  Last Age State
           0    Chris  Zack 43  CA
           1    Marco  Bart 22  NV
           2    Pearl  Muth 15  HI

   ... and its selection() method would yield: [0, 1, 2] -- which is a list
   of all the records, in order.

   After calling $t->sort([Last]), selection() would yield [1, 2, 0]. So
   displaying the table in "selection" order would yield:

           Rec# First  Last Age State
           1    Marco  Bart 22  NV
           2    Pearl  Muth 15  HI
           0    Chris  Zack 43  CA

   IMPORTANT: sorting does not alter any data in the table. It merely
   alters the _Selection parameter (which you can then get and set using
   the selection() methods described above).

   If you want to permanently alter the table's data in memory so that the
   new sorted order becomes the "natural" order, you can use the cull()
   method to modify the original object, the snapshot() method to make a
   new object, or use the write() method to write the data to disk in
   selected/sorted order and then read() it back again.

 Using the Named-parameter calling convention with sort()

   You may specify any combination of the parameters listed above when
   calling sort(). Any you specify will be used IN PLACE OF the
   corresponding parameters already found in the object.

   If you specify _Selection using the named-parameter calling, the sort()
   method reserves the right to "own" the list you provide, and use it as
   the object's new _Selection, possibly discarding the previous
   _Selection, if any and modifying the one you provided. So don't make any
   assumptions about ownership of that list object after calling sort().
   Luckily, you will rarely need to provide _Selection explicitly since
   generally you'll want to be sorting the selection() already inherent in
   the object.

   sort() returns the _Selection list owned by the object (the same list
   that would be returned if you called the selection() method immediately
   after calling sort()).

   See the next sections for complete descriptions of _SortOrder and other
   sorting parameters.

SORT ORDER
           ## Getting / Setting table's default _SortOrder

           $t->sortorder()         ## Get sortorder (default is [])

           my $Order = [qw(Last First State Zip)];
           $t->sortorder($Order)   ## Set sortorder (use [] for none)

           $t->sortorder_default() ## Get the object's default sort order ([])

   The sort order is an optional list of field names on which to sort and
   sub-sort the data when sorting is requested. The field names must be the
   names of actual columns in the table. The names in the sort order do not
   necessarily need to coincide with the custom fieldlist if any.

   There is one special value that can be included: _RecNum. This sorts on
   the imaginary "record number" field. So for example, you could specify a
   sort order this way:

           [qw(Last First _RecNum)]

   (There is no point in putting _RecNum anywhere except at the end of the
   sort order because no two records will ever have the same record number
   so there will be no further need to disambiguate by referring to
   additional fields.)

   Sorting by _RecNum adds a bit of computational overhead because sort()
   first builds a record number vector for use in sorting, so for very
   large tables, don't do it unless you really need it.

   A sort order can be specified each time the object is sorted (see the
   sort() method for details).

   Or, the object's sort order can be set once, and then sort() will use
   that sort order when no other sort order is specified.

   If sorting is done when there is no sort order present in the object or
   specifed for the sort() method, the selection is sorted by record number
   (i.e. it is "unsorted" or returned to its "natural" order).

   In order words, a sortorder that is undef or [] is considered the same
   as: [qw(_RecNum)]. This is sometimes called "unsorting".

   In order to decide how values in each field should be compared, sort()
   is informed by SortSpecs (specifying SortType and SortDirection for each
   field) and by SortRoutines, each of which may similarly either be
   pre-set for the object or specified when calling sort() -- see below for
   further details.

SORT SPECIFICATIONS
           ## Getting / Setting table's default _SortSpecs

           $t->sortspecs()         ## Get sortspecs (default is {} -- none)

           my $Specs = {Last => {SortType       => 'String' ,
                                 SortDirection  => -1        },
                        Zip  => {SortType       => 'Integer' }};

           $t->sortspecs($Specs)   ## Set sortspecs

           $t->sortspecs_default() ## Get the object's default sort specs ({})

   The sortspecs are an optional hash mapping field names to "sort
   specifications".

   Each field's sort specification may specify zero or more of these
   values:

   SortType
       the sort type to use (For example: String, Integer)

   SortDirection
       the sort direction (1: ascending, -1: descending)

   Sortspecs can be specified when calling the sort() routine, or, a set of
   specs can be placed beforehand into the object itself and those will be
   used by sort() if no other specs are given.

   For any field listed in the sort order at the time of sorting, but
   lacking a sort spec or any component of the sort spec, the object's
   default sort type (see sorttype_default()) and default sort direction
   (see sortdirection_default()) will be used.

   In addition to getting/setting sort specs as a whole, they may be
   gotten/set on a per-field basis, too:

           sortspec($Field)       ## Get sortspec for $Field or default spec

           my $Spec   = {SortType => 'Integer', SortDirection => -1};
           sortspec('Zip', $Spec) ## Set sortspec

           sortspec_default()     ## Get a sortspec with all defaults filled in

   For any $Field not found in the object's sortspecs, sortspec($Field)
   returns the same thing returned by sortspec_default(), which is a
   sortspec filled in with the default sort type and sort direction (see
   below).

   For a list of available built-in SortTypes, and instructions for how to
   define your own, see SORT ROUTINES, below.

DEFAULT SORT DIRECTION
           ## Getting / Setting table's default _DefaultSortDirection

           $t->sortdirection_default()     ## Get default sort direction

           $t->sortdirection_default(-1)   ## Set default sort direction

   Each element in a sort specification can optionally specify a sort
   direction.

   1 = ascending, -1 = descending

   For any sort specs that don't specify a direction, the object's default
   sort direction will be used. Use these routines to get/set the default
   sort direction.

DEFAULT SORT TYPE
           ## Getting / Setting table's default _DefaultSortType

           $t->sorttype_default()          ## Get default sort type

           $t->sorttype_default('Integer') ## Set default sort type

   Each element in a sort specification can optionally specify a sort type.
   The sort type is a string (like 'String' or 'Integer' or 'Date') that
   selects from one or more sort routines. (See Sort Routines, below).

   There are several sort routines built into the CTable object, and you
   can also add as many of your own routines (and hence Sort Types) as you
   like or need. This allows for very flexible sorting.

   For any sort specs that don't specify a type, the object's default sort
   type will be used. Use these routines to get/set the default sort type,
   which initially is 'String'.

SORT ROUTINES: BUILTIN AND CUSTOM
           ## Getting / Setting table's custom sort routines (_SRoutines)

           $t->sortroutine($Type)       ## Get a sort routine for $Type

           $t->sortroutine($Type, $Sub) ## Set a sort routine for $Type

           $t->sortroutine($Type, 0   ) ## Remove sort routine for $Type
           $t->sortroutine_set($Type)

           $t->sortroutines()           ## Get hash of any sort routines

           $t->sortroutines_builtin()   ## Get hash of builtin routines

   Each SortType in the sortspecs should have a corresponding sort routine
   (any unrecognized type will be sorted using the 'String' sort routine).

   The sort() command looks up the appropriate sort routine for each field
   it is asked to sort, based on the SortType for that field, as given in
   the sortspecs, as described above.

   Builtin sort types, recognized and implemented natively by this module,
   are:

           String   ## Fastest case-sensitive compare (data is string)
           Text     ## Insensitive compare (lowercases, then compares)
           Number   ## Number works for floats or integers
           Integer  ## Faster than floats.  Uses "use integer"
           DateSecs ## Same as integer; assumes date in seconds
           Boolean  ## Treats item as a Perlish boolean (empty/undef = false)

   The above sort types are always recognized. Additional sort types may be
   added by subclasses (and could shadow the builtin implementations of the
   above types if desired) and/or may be added to instances (and again
   could shadow the above implementations), and/or may be specified when
   the sort() method is called, once again optionally shadowing any deeper
   definitions.

CUSTOM SORT ROUTINE INTERFACE
   A custom sort routine is called with two arguments, each of which is a
   pointer to a scalar. The sort routine should dereference each pointer
   and compare the resulting scalars, returning -1 if the first scalar is
   smaller than the second, 1 if it is larger, and 0 if they are considered
   equal.

   For example, here is the built-in comparison routine for 'String':

           sub {   $ {$_[0]}  cmp    $ {$_[1]} }

   NOTE: Your custom sort routines should NOT compare $a and $b as with
   Perl's builtin sort() command.

   Examine the variable $BuiltinSortRoutines in this module's
   implementation to see some additional examples of sort routines.

   Internally, sort() calls the sortroutines() method to get a hash that
   should consist of all builtin sort routines with the per-object sort
   routines, if any, overlaid. sortroutines() in turn calls the
   sortroutines_builtin() method to get a copy of the hash of all builtin
   sort routines for the object. (So a subclass could easily add additional
   SortTypes or reimplement them by just overriding sortroutines_builtin()
   and adding its own additional routines to the resulting hash.)

   sortroutine() may be called to get or set a custom sort routine for a
   given type in the given object.

   There is no way to directly manipulate the builtin sort routines for the
   entire class. To accomplish that, you should define and use a subclass
   that extends sortroutines_builtin() to add its own routines.

   For example:

           BEGIN
           {   ## A subclass of Data::CTable with an INetAddr SortType.
               package IATable;    use vars qw(@ISA);    @ISA = qw(Data::CTable);

               sub sortroutines_builtin
               {
                   my $this = shift;
                   my $CustomRoutines =
                   {INetAddr =>
                    sub {use integer; ip2int($ {$_[0]}) <=> ip2int($ {$_[1]})}};
                   my $AllRoutines =
                   {%{$this->SUPER::sortroutines_builtin()} %$CustomRoutines};
                   return($AllRoutines);
               };

               sub ip2int {.....}  $# Could memoize & inline for efficiency
           }

           my $Table = IATable::new(......);

   The IATable class would then have all the same features of Data::CTable
   but would then also support the INetAddr SortType.

FREEZING SELECTION & FIELD LIST
           ## Freeze data layout: re-order columns; omit unused fields

                   $t->cull(...params...)     ## Rebuild table in order
           my $s = $t->snapshot(...params...) ## Make copy as if rebuilt

   The cull() method re-writes all data in the table to be in the order
   indicated in _Selection (if present). This will cause any records not
   listed in _Selection to be omitted (unless selection is null in which
   case all records are retained in original order).

   In addition, if there is a custom field list present, it removes any
   fields NOT mentioned in _FieldList.

   The snapshot() method is similar, except instead of modifying the object
   itself, it makes a copy of the object that's equivalent to what cull()
   would have created, and returns that new object, leaving the original
   untouched. (All data structures are deep-copied from the old object to
   the new one, leaving the objects totally independent.)

   cull() and snapshot() both take two optional named parameters:
   _FieldList and/or _Selection to be used in place of the corresponding
   parameters found in the object.

   If only a single argument is supplied, it is assumed to be _Selection.

LINE ENDINGS
           ## Get current value

           $t->lineending()          ## Get actual setting: string or symbol
           $t->lineending_symbol()   ## Get setting's symbolic value if possible
           $t->lineending_string()   ## Get setting's string value if possible

           ## Set value

           $t->lineending($Ending)   ## Will be converted internally to symbol

           ## Convert a value to symbol or string form

           $t->lineending_symbol($L) ## Convert string form to symbolic form
           $t->lineending_string($L) ## Convert symbol form to string form

           ## Get internal conversion hash tables

           $t->lineending_symbols()  ## Hash ref mapping known strings to symbols
           $t->lineending_strings()  ## Hash ref mapping known symbols to strings

   Use these accessor functions to get/set the _LineEnding parameter.

   You can set the parameter in either string or symbol form as you wish.
   You can get it in its raw, as-stored, form, or, you can get it in string
   form or symbol form as desired.

   Finally, some utility conversion calls allows you to convert a string
   you have on hand to a symbolic form. For example:

           $L = "\x0D";
           print ("This file uses " . $t->lineending_symbol($L) . " endings.");

   This would print:

           This file uses mac endings.

AUTOMATIC CACHEING
   By default, Data::CTable makes cached versions of files it reads so it
   can read them much more quickly the next time. Optionally, it can also
   cache any file it writes for quicker re-reading later.

   On Unix systems, cache files are always created with 0666 (world-write)
   permissions for easy cleanup.

   When reading files, Data::CTable checks the _CacheOnRead parameter. If
   that parameter is true, which it is by default, the module tries to find
   an up-to-date cache file to read instead of the original. Reading a
   cache file can be 10x faster than reading and parsing the original text
   file.

   In order to look for the cache file, it must first calculate the path
   where the cache file should be located, based on the _FileName of the
   file to be read.

   The path of the cache file is calculated as follows:

   If the _CacheSubDir parameter is a RELATIVE PATH, then it is appended to
   the directory component of _FileName to arrive at the directory to use
   to store the cache file. If it is an ABSOLUTE PATH, then _CacheSubDir is
   used by itself. (The trailing path separator is optional and an
   appropriate one will be added by Data::CTable if it is missing.)

   The file name of the cache file is calculated as follows:

   If the _CacheExtension parameter is specified, it is appended to the
   base file name component from the _FileName parameter. If you want the
   cached file name to be the same as the name of the original file, you
   can set _CacheExtension to "", which is not recommended.

   Then, the cache path and cache file name are joined to arrive at the
   name of the cache file. If both _CacheSubDir and _CacheExtension were
   empty, then the cache file path will be the same as the _FileName, and
   Data::CTable will refuse to either read or write a cache file, so
   setting these fields both to empty is equivalent to setting _CacheOnRead
   to false.

   The cache file contains a highly-efficient representation of all the
   following data that would otherwise have to be determined by reading and
   parsing the entire text file:

           - All the data columns (field values)
           - _FieldList:  The list of fields, in order
           - _HeaderRow:  Whether a header row is / should be present
           - _LineEnding: The line ending setting
           - _FDelimiter: The field delimiter setting

   If found prior to a read(), AND, the date of the cache file is LATER
   than the date of the original file, the cache file is used instead. (If
   the date is EARLIER, then the cache file is ignored because it can be
   presumed that the data inside the text file is newer.)

   If cacheing is ON, then after successfully reading the text file (either
   because there was no cache file yet or the cache file was out of date or
   corrupted or otherwise unusable), read() will then try to create a cache
   file. This, of course, takes some time, but the time taken will be more
   than made up in the speedup of the next read() operation on the same
   file.

   If creating the cache file fails (for example, because file permissions
   didn't allow the cache directory to be created or the cache file to be
   written), read() generates a warning explaining why cacheing failed, but
   the read() operation itself still succeeds.

   No parameters in the object itself are set or modified to indicate the
   success or failure of writing the cache file.

   Similarly, there is no way to tell whether a successful read() operation
   read from the cache or from the original data file. If you want to be
   SURE the reading was from the data file, either turn off _CacheOnRead,
   or call the read_file() method instead of read().

   NOTE: because the name of the cache file to be used is calculated just
   before the read() is actually done, the cache file can only be found if
   the _CacheSubDir and _CacheExtension are the same as they were when the
   cache was last created. If you change these parameters after having
   previously cached a file, the older caches could be "orphaned" and just
   sit around wasting disk space.

 Cacheing on write()

   You may optionally set _CacheOnWrite (default = false) to true. If done,
   then a cache file will be saved for files written using the write()
   command. Read about write() below for more about why you might want to
   do this.

AUTOMATIC DIRECTORY CREATION
   When Data::CTable needs to write a file, (a cache file or a data file),
   it automatically tries to create any directories or subdirectories you
   specify in the _FileName or _CacheSubDir parameters.

   If it fails while writing a data file, write() will fail (and you will
   be warned). If it fails to create a directory while writing a cache
   file, a warning will be issued, but the overall read() or write()
   operation will still return a result indicating success.

   Any directories created will have the permissions 0777 (world-write) for
   easy cleanup.

   Generally, the only directory the module will have to create is a
   subdirectory to hold cache files.

   However, since other directories could be created, be sure to exercise
   caution when allowing the module to create any directories for you on
   any system where security might be an issue.

   Also, if the 0666 permissions on the cache files themselves are too
   liberal, you can either 1) turn off cacheing, or 2) call the
   prep_cache_file() method to get the name of the cache file that would
   have been written, if any, and then restrict its permissions:

           chmod (0600, $this->prep_cache_file());

READING DATA FILES
           ## Replacing data in table with data read from a file

           $t->read($Path)     ## Simple calling convention

           $t->read(           ## Named-parameter convention

                ## Params that override params in the object if supplied...

                _FileName      => $Path, ## Full or partial path of file to read

                _FieldList     => [...], ## Fields to read; others to be discarded

                _HeaderRow     => 0,     ## No header row (_FieldList required!)

                _LineEnding    => undef, ## Text line ending (undef means guess)
                _FDelimiter    => undef, ## Field delimiter (undef means guess)

                _ReturnMap     => 1,     ## Whether to decode internal returns
                _ReturnEncoding=>"\x0B", ## How to decode returns.
                _MacRomanMap   => undef, ## Whether/when to read Mac char set

                _CacheOnRead   => 0,     ## Enable/disable cacheing behavior
                _CacheExtension=> ".x",  ## Extension to add to cache file name
                _CacheSubDir   => "",    ## (Sub-)dir, if any, for cache files

                ## Params specific to the read()/write() methods...

                _MaxRecords    => 200,   ## Limit on how many records to read
                )

           $t->read_file()     ## Internal: same as read(); ignores cacheing

   read() opens a Merge, CSV, or Tab-delimited file and reads in all or
   some fields, and all or some records, REPLACING ANY EXISTING DATA in the
   CTable object.

   Using the simple calling convention, just pass it a file name. All other
   parameters will come from the object (or will be defaulted if absent).
   To specify additional parameters or override any parameters in the
   object while reading, use the named-parameter calling convention.

   See the full PARAMETER LIST, above, or read on for some extra details:

   _ReturnMap controls whether return characters encoded as ASCII 11 should
   be mapped back to real newlines (""\n"") when read into memory. If
   false, they are left as ASCII 11 characters. (default is "true")

   _ReturnEncoding controls the character that returns are encoded as, if
   different from ASCII 11.

   _FieldList is an array (reference) listing the names of fields to
   import, in order (and will become the object's _FieldList upon
   successful completion of the read() operation). If not provided and not
   found in the object, or empty, then all fields found in the file are
   imported and the object's field list will be set from those found in the
   file, in the order found there. If _HeaderRow is false, then this
   parameter is required (either in the object or as a formal parameter)
   and is assumed to give the correct names for the fields as they actually
   occur in the file. If _HeaderRow is true and _FieldList is provided,
   then _FieldList specifies the (sub-)set of fields to be read from the
   file and others will be ignored.

   _HeaderRow, which defaults to true, if set to false, tells read() to not
   expect a header row showing the field names in the file. Instead, it
   assumes that the _FieldList gives those (and _FieldList must therefore
   be specified either as a parameter or an existing parameter in the
   object).

   _MaxRecords (optional) is an upper limit on the number of fields to
   import. If not specified, or zero, or undef, then there is no limit; all
   records will be imported or memory will be exhausted.

   read() returns a Boolean "success" code.

   If read() returns false, then it will also have set the _ErrorMsg
   parameter in the object. It may or may not have partially altered data
   in the object if an error is encountered.

   After a successful read:

   fieldlist() (the object's _FieldList parameter) tells which fields were
   actually read, in what order. It may omit any fields requested in
   _FieldList that were not actually found in the file for whatever reason.

   length() tells how many fields were read.

   The selection() is reset to no selection (all selected / unsorted)

   The object's _FileName parameter contains the path to the file that was
   read. If the _FileName you specified did not have a path, then _FileName
   will be prepended with a path component indicating "current directory"
   (e.g. "./" on Unix).

   _FDelimiter will contain the actual delimiter character that was used to
   read the file (either tab or comma if the delimiter was guessed, or
   whatever delimiter you specified).

   _LineEnding will contain the actual line-ending setting used to read the
   file. This will be either "mac" ("\x0D"), "unix" ("\x0D"), or "dos"
   ("\x0D\x0A") if the line endings were guessed by read(). Otherwise it
   will be whatever _LineEnding you specified.

FILE FORMAT NOTES
   As mentioned, read() allows the following flexibilities in reading
   text-based tabular data files:

   You may specify the line endings (record delimiters), or it can guess
   them (mac, unix, dos are supported).

   You may specify the field delimiters, or it can guess them (tab and
   comma are supported).

   It can get field names from a header row, or, if there is no header row,
   you can tell it the field names, in order.

   You can tell it whether or not to decode embedded returns in data
   fields, and if so, which character they were encoded as.

   Beyond supporting the above flexible options, read() makes the following
   non-flexible assumptions:

   Fields must NOT contain unencoded returns -- that is: whatever character
   sequence is specified for _LineEnding will NEVER occur inside a field in
   the text file; in addition, the current platform's definition of ""\n""
   will NEVER occur; these characters if present in field data, MUST have
   been encoded to some safe character string before the file was created.

   Each field may OPTIONALLY be surrounded with double-quote marks.
   However, if the field data itself contains either a double-quote
   character (""") or the current file's field delimiter (such as tab or
   comma), then the field MUST be surrounded with double-quotes.
   (Currently, all data written by Data::CTable have all field values
   surrounded by double-quotes, but a more selective policy may be used in
   the future.)

   If a field contains a double-quote character, then each double-quote
   character in the field must be encoded as """" -- i.e. each """ in the
   original data becomes """" in the text file.

   Data files may not mix line-ending types or field delimiter types. Once
   determined, the same endings and delimiters will be used to read the
   entire file.

   The fields recognized on each line will either be determined by the
   header row or the _FieldList provided by the caller. Any extra fields on
   any given line will be ignored. Any missing fields will be treated as
   undef/empty.

   If you are having trouble reading a delimited text file, check that all
   data in the file obeys these assumptions.

WRITING DATA FILES
           ## Writing some or all data from table into a data file

           $t->write($Path)              ## Simple calling convention

           $t->write(                    ## Named-parameter convention

                ## Params that override params in the object if supplied...

                _FileName      => $Path, ## "Base path"; see _WriteExtension

                _WriteExtension=> ".out",## Insert/append extension to _FileName

                _FieldList     => [...], ## Fields to write; others ignored
                _Selection     => [...], ## Record (#s) to write; others ignored

                _HeaderRow     => 0,     ## Include header row in file

                _LineEnding    => undef, ## Record delimiter (default is "\n")
                _FDelimiter    => undef, ## Field delimiter (default is comma)

                _ReturnMap     => 1,     ## Whether to encode internal returns
                _ReturnEncoding=>"\x0B", ## How to encode returns
                _MacRomanMap   => undef, ## Whether/when to write Mac char set

                _CacheOnWrite  => 1,     ## Enable saving cache after write()
                _CacheExtension=> ".x",  ## Extension to add to cache file name
                _CacheSubDir   => "",    ## (Sub-)dir, if any, for cache files

                ## Params specific to the read()/write() methods...

                _MaxRecords    => 200,   ## Limit on how many records to write
                )

           $t->write_file()    ## Internal: same as write(); ignores cacheing

   write() writes a Merge, CSV, or Tab-delimited file.

   It uses parameters as described above. Any parameters not supplied will
   be gotten from the object.

   Using the simple calling convention, just pass it a path which will
   override the _FileName parameter in the object, if any.

   All other parameters will come from the object (or will be defaulted if
   absent).

   If no _FileName or path is specified, or it is the special string "-"
   (dash), then the file handle \ * STDOUT will be used by default (and you
   could redirect it to a file). You can supply any open file handle or
   IO::File object of your own for the _FileName parameter.

   If write() is writing to a file handle by default or because you
   specified one, then no write-cacheing will occur.

   To specify additional parameters or override any parameters in the
   object while reading, use the named-parameter calling convention.

   If the object's data was previously filled in using new() or read(),
   then the file format parameters from the previous read() method will
   still be in the object, so the format of the written file will
   correspond as much as possible to the file that was read().

   write() returns the path name of the file actually written, or the empty
   string if a supplied file handle or STDOUT was written to, or undef if
   there was a failure.

   If write() returns undef, then it will also have set the _ErrorMsg
   parameter in the object.

   write() never modifies any data in the object itself.

   Consequently, if you specify a _FieldList or a _Selection, only those
   fields or records will be written, but the corresponding parameters in
   the object itself will be left untouched.

 How write() calculates the Path

   The _FileName parameter is shared with the read() method. This parameter
   is set by read() and may be overridden when calling write().

   In the base implementation of Data::CTable, write() will try not to
   overwrite the same file that was read, which could possibly cause data
   loss.

   To avoid this, it does not use the _FileName parameter directly.
   Instead, it starts with _FileName and inserts or appends the value of
   the _WriteExtension parameter (which defaults to ".out") into the file
   name before writing.

   If the _FileName already has an extension at the end, write() will place
   the _WriteExtension BEFORE the final extension; otherwise the
   _WriteExtension will be placed at the end of the _FileName.

   For example:

           Foobar.txt        ==>  Foobar.out.txt
           Foobar.merge.txt  ==>  Foobar.merge.out.txt
           My_Merge_Data     ==>  My_Merge_Data.out

   If you DON'T want write() to add a _WriteExtension to _FileName before
   it writes the file, then you must set _WriteExtension to empty/undef
   either in the object or when calling write(). Or, you could make a
   subclass that initializes _WriteExtension to be empty. If
   _WriteExtension is empty, then _FileName will be used exactly, which may
   result in overwriting the original data file.

   Remember: write() returns the path name it actually used to successfully
   write the file. Just as with read(), if the _FileName you specified did
   not have a path, then write() will prepend a path component indicating
   "current directory" (e.g. "./" on Unix) and this will be part of the
   return value.

 Cacheing with write()

   By default, Data::CTable only creates a cached version of a file when it
   reads that file for the first time (on the assumption that it will need
   to read the file again more often than the file's data will change.)

   But by default, it does not create a cached version of a file when
   writing it, on the assumption that the current program probably will not
   be re-reading the written file and any other program that wants to read
   it can cache it at that time.

   However, if you want write() to create a cache for its output file, it
   is much faster to create it on write() than waiting for the next read()
   because the next read() will be able to use the cache the very first
   time.

   To enable write-cacheing, set _CacheOnWrite to true. Then, after the
   write() successfully completes (and only if it does), the cached version
   will be written.

FORMATTED TABLES (Using Data::ShowTable)
           ## Get formatted data in memory

           my $StringRef = $t->format();     ## Format same data as write()
           my $StringRef = $t->format(10);   ## Limit records to 10
           my $StringRef = $t->format(...);  ## Specify arbitrary params
           print $$StringRef;

           ## Write formatted table to file or terminal

           $t->out($Dest, ....);## $Dest as follows; other params to format()
           $t->out($Dest, 10, ....) ## Limit recs to 10; params to format()

           $t->out()            ## print formatted data to STDOUT
           $t->out(\*STDERR)    ## print to STDERR (or any named handle)
           $t->out("Foo.txt")   ## print to any path (file to be overwritten)
           $t->out($FileObj)    ## print to any object with a print() method

   out() takes a first argument specifying a destination for the output,
   then passes all other arguments to format() to create a nice-looking
   table designed to be human-readable; it takes the resulting buffer and
   print()s it to the destination you specified.

   Sample output:

            +-------+------+-----+-------+
            | First | Last | Age | State |
            +-------+------+-----+-------+
            | Chris | Zack | 43  | CA    |
            | Marco | Bart | 22  | NV    |
            | Pearl | Muth | 15  | HI    |
            +-------+------+-----+-------+

           (Note extra space character before each line.)

   The destination may be a file handle (default if undef is \*STDOUT), a
   string (treated as a path to be overwritten), or any object that has a
   print() method, especially an object of type IO::File.

   The main purpose of out() is to give you a quick way to dump a table
   when debugging. out() calls format() to create the output, so read on...

   format() produces a human-readable version of a table, in the form of a
   reference to a string buffer (which could be very large), and returns
   the buffer to you. Dereference the resulting string reference before
   using.

   If format() is given one argument, that argument is the _MaxRecords
   parameter, which limits the length of the output.

   Otherwise, format() takes the following named-parameter arguments, which
   can optionally override the corresponding parameters, if any, in the
   object:

           _FieldList        ## Fields to include in table
           _Selection        ## Records to be included, in order

           _SortSpecs        ## SortType controls number formatting
           _DefaultSortType

           _MaxRecords       ## Limit number of records output

           _MaxWidth         ## Limit width of per-col. data in printout

   format() will obey _MaxRecords, if you'd like to limit the number of
   rows to be output. _MaxRecords can also be a single argument to
   format(), or a second argument to out() if no other parameters are
   passed.

   format() also recognizes the _SortSpecs->{SortType} and _DefaultSortType
   parameters to help it determine the data types of the fields being
   formatted. Fields of type "Number" are output as right-justified floats;
   "Integer" or "Boolean" are output as right-justified integers, and all
   others (including the default: String) are output as left-justified
   strings.

   In addition, there is one parameter uniquely supported by format() and
   out():

   _MaxWidth ||= 15;
   _MaxWidth specifies the maximum width of columns. If unspecifed, this
   will be 15; the minimum legal value is 2. Each column may actually take
   up 3 more characters than _MaxWidth due to divider characters.

   The data to be output will be examined, and only the necessary width
   will be used for each column. _MaxWidth just limits the upper bound, not
   the lower.

   Data values that are too wide to fit in _MaxWidth spaces will be
   truncated and the tilde character "~" will appear as the last character
   to indicate the truncation.

   Data values with internal returns will have the return characters mapped
   to slashes for display.

   format() and out() will NOT wrap entries onto a second line, like you
   may have seen Data::ShowTable::ShowBoxTable do in some cases. Each
   record will get exactly one line.

   format() and out() ignore the _HeaderRow parameter. A header row showing
   the field names is always printed.

   format() and out() make no attempt to map upper-ascii characters from or
   to any particular dataset. The encoding used in memory (generally ISO
   8859-1 by default) is the encoding used in the output. If you want to
   manipulate the encoding, first call format(), then change the encoding,
   then format the resulting table.

APPENDING / MERGING / JOINING TABLES
           ## Append all records from a second table

           $t->append($Other)                ## Append records from $Other
           $t->append_file($File, $Params)   ## Append from new($Params, $File)
           $t->append_files($Files, $Params) ## Call append_file for all files
           $t->append_files_new($Files, $Params) ## Internal helper routine

           ## Combine all fields from a second table

           $t->combine($Other)                ## Combine fields from $Other
           $t->combine_file($File, $Params)   ## Combine new($Params, $File)
           $t->combine_files($Files, $Params) ## combine_file on each file

           ## Left-join records from a second table (lookup field vals)

           $t->join      ($Other,          $KeyField1, [$KeyField2, $Fields])
           $t->join_file ($File,  $Params, $KeyField1, [$KeyField2, $Fields])
           $t->join_files($Files, $Params, $KeyField1, [$KeyField2, $Fields])

   The append() method concatenates all the records from two CTable objects
   together -- even if the two tables didn't start out with exactly the
   same fields (or even any of the same fields).

   It takes all the data records from another CTable object and appends
   them into the present table. Any columns present in the $Other table but
   not in the first table, are created (and the corresponding field values
   in the first table will all be empty/undef). Similarly, any columns
   present in $t but not present in $Other will be extended to the correct
   new length as necessary and the field values in the original columns
   will be empty/undef. Columns present in both will, of course, have all
   the data from both the original sets of data.

   All data from the second table is brought into the first one. No attempt
   whatsoever is made to eliminate any duplicate records that might result.

   The number of records (length()) after this call is the sum of the
   length() of each of the tables before the operation.

   IMPORTANT NOTE: The data from the $Other object is COPIED in memory into
   the new object. This could be hard on memory if $Other is big. Might
   want to be sure to discard $Other when you're done with it.

   $Other is left untouched by the operation.

   All columns from both tables are combined whether or not they are
   mentioned in the custom field list of either.

   The custom field lists, if present in either table object, are
   concatenated into this object's custom field list, but with duplications
   eliminated, and order retained.

   Any existing custom selections, custom sort order, sort specs, and/or
   sort routines are also combined appropriately, with settings from this
   object taking precedence over those from $Other anywhere the two have
   conflicting settings.

   append_file() takes a file name and optional $Params hash. It uses those
   to create a new() object with data read from the file. Then, the new
   table is appended to $t using append() and then the new table is
   discarded.

   append_files() is a convenience function that calls append_file() on
   each file in a list, using the same optional $Params for each.

   append_files_new() is the internal routine that implements the
   processing done by new() on the optional list of files to be read. It
   does the following: It calls read() on the first file in the list. Then,
   it calls append_files() to read the remaining into their own new()
   objects of the same class as $t and using the same $Params to new() (if
   any were supplied). Then each of these is append()-ed in turn to $t and
   discarded. The final result will be that $t will hold a concatenation of
   all the data in all the files mentioned. However, consistent with the
   behavior of append(), the _FileName parameter and other
   read()-controlled settings will correspond to the first file read. The
   intermediate objects are discarded.

   NOTE: As with new() and read(), if a non-empty _FieldList Param is
   specified, the read() methods called internally by the append_file*()
   methods will read only the fields mentioned and will ignore any other
   fields in the files.

 Combining tables

   combine() adds columns from a second table into the current one.

   CAUTION: You should only use combine() when you have two tables where
   all the (possibly selected) records in the second table line up
   perfectly with all the (unselected) records in the first table -- in
   other words, each table before combine() should contain a few of the
   columns of the new table -- for example, maybe one table contains a
   column of file names, and the other contains columns of corresponding
   file sizes and modification times. If you don't understand the
   consequences of combine, don't use it or you could end up with some
   records whose field values don't refer to the same object. (Maybe you
   meant to use append() or join() instead.)

   If the second table has a custom field list, only those columns are
   brought in.

   If any column in the second table has the same name as one in the
   current table, the incoming column replaces the one by the same name.

   All columns are COPIED from the second table, so the first table owns
   the new data exclusively.

   If the second table has a selection, only those records are copied, in
   selection order. (select_all() first if that's not what you want.)

   The selection in the first table, if any, is ignored during the combine.
   If this isn't what you want, then consider using cull() before
   combine().

   Field list and sort order are concatenated (but retaining uniqueness:
   second mentions of a field in the combined lists are omitted).

   Custom sort routines and sort specs are combined, with those in the
   first table taking precedence over any copied in with the same name.

   The custom _Selection from the first table, if any, is retained. (It
   will initially omit any records added by extend()).

   All other parameters from the first table are retained, and from the
   second table are ignored.

   combine() calls extend() after combining to ensure that all columns have
   the same length: if either the older or newer columns were shorter, they
   will all be set to the length of the longest columns in the table --
   creating some empty field values at the end of the lengthened columns.

   combine_file() does the same as combine() except starting with a file
   name, first creating the $Other object by creating it using new($Params,
   $File), then discarding it after combining.

 Joining tables (Looking up data from another table)

   join() looks up field values from a second table, based on common values
   in key fields which may have different or the same names in each table.
   It adds columns to the current table if necessary to hold any new field
   values that must be brought in.

   join() never adds any new or non-matching records to the table: records
   where the lookup fails will simply have empty/undef values in the
   corresponding columns.

           ## Example:

           $t->join     ($People,          'FullName', 'FirstAndLast'); ## or
           $t->join_file("People.txt", {}, 'FullName', 'FirstAndLast');

   Here's how join() calculates the list of fields to bring in:

           - Legal field names from the optional $Fields list, if supplied
           - Otherwise, the fieldlist() from second table
           - ... minus any fields with same name as $KeyField1 or $KeyField2

   Join starts by adding new empty columns in the first table for any field
   to be brought in from the second but not yet present in the first.

   Here's how join() calculates the records eligible for lookup:

           - Join only modifies the selected records in the first table
           - Join only looks up values from selected records in second table

   (If you want all records to be used in both or either table, call the
   table's select_all() method before calling join().)

   Then, for every selected record in $t (using the example above), join
   examines the FullName field ($KeyField1), and looks up a corresponding
   entry (must be 'eq') in the FirstAndLast field ($KeyField2) in the
   second table.

   IMPORTANT NOTE ABOUT KEY LENGTH: To speed lookup, hash-based indices are
   made. The strings in $Key1 and $Key2 fields should not be so long that
   the hash lookups bog down or things could get ugly fast. There is no
   fixed limit to hash key length in Perl, but fewer than 128 characters in
   length is longer than customary for such things. (Many systems require
   text-based keys to be no longer than 31 characters.) So be judicious
   about the values in $Key1 and $Key2 fields.

   The first record found in the second table's selection with a matching
   value in the key field is then copied over (but only the appropriate
   fields are copied, as explained above). Any field values being brought
   over will REPLACE corresponding field values in the first table,
   possibly overwriting any previous values if the field being looked up
   was already present in the first table and contained data.

   The first table's _FieldList is updated to reflect new fields added.

   Its _Selection is untouched.

   Its _SortOrder is untouched.

   Its _SortSpecs are augmented to include any entries from the second
   table that should be brought over due to the field additions.

   Its _SRoutines are augmented to add new ones from the second table.

   All other parameters of table 1 are untouched.

   The second table is not modified. No data structures will be shared
   between the tables. Data is only copied.

   join_file() calls join() after creating a seond table from your $File.

   join_files() calls join_file() repeatedly for each file in a list, but
   it is important to note that each file in the list of files to be joined
   must have a $Key2 field -- AND, that any values looked up from the
   second file will overwrite any values of the same key found in the first
   file, and so on. You probably will not ever need join_files(). It is
   mainly here for completeness.

INVERTING A TABLE'S ROWS/COLUMNS
           ## Re-orient table's data using vals from $ColName as field names...
           $t-invert($ColName)

   Sometimes a situation gives you a table that's initially organized with
   column data in rows, and field names in one of the columns, so you need
   to flip the table in order to be able to work meaningfully with it.

   "Inverting" a table means to rewrite each row as a column. One row is
   designated to be used as the field names.

   For example, consider this table:

           F01    F02   F03   F04
           ------------------------
           First  Chris Agnes James
           Last   Bart  Marco Nixon
           Age    22    33    44

   Calling invert() using field names from "F01"...

           $t->invert('F01');

   ... would change the table to look like this:

           First  Last  Age
           ----------------
           Chris  Bart  22
           Agnes  Marco 33
           James  Nixon 44

   The field F01 which formerly contained the field names, is now gone, and
   the remaining data columns have been converted from their old row
   orientation into a column orientation.

PROGRESS MESSAGES
           ## Printing a progress message....

           $t->progress($Msg)       ## Print a message per current settings

           ## Progress settings applying to this object only...

           $t->progress_get()       ## Get current progress setting

           $t->progress_set(1)      ## Use progress_default() method
           $t->progress_set($Sub)   ## Set a custom progress routine
           $t->progress_set(0)      ## Disable progress
           $t->progress_set(undef)  ## Use class's settings (default)...

           ## Class's settings (for instances with _Progress == undef)

           $t->progress_class()     ## Get current setting.

           $t->progress_class(1)    ## Use progress_default() method
           $t->progress_class($Sub) ## Set shared custom prog routine
           $t->progress_class(0)    ## Disable class-default progress

           Data::CTable->progress_class(..) ## Call without an object

           ## Call builtin default progress method regardless of settings

           $t->progress_default($Msg) ## Default prog. routine for class

           ## Generate a warning (used internally by other methods)

           $t->warn($Msg)   ## In this class, calls progress_default()

           ## Timed progress: print msg to start, then at most once/2 sec

           $t->progress_timed($Op, $Item)  ## Re-print msg every 2 sec
           $t->progress_timed($Op, $Item, $Pos, $Tot) ##... with % readout
           $t->progress_timed($Op, $Item, $Pos, $Tot, $Wait) ## Not 1st x

           $t->progress_timed_default($Msg)  ## Called by progress_timed

   Data::CTable is especially useful in creating batch-oriented
   applications for processing data. As such, routines that may perform
   time-consuming tasks will, by default, generate helpful progress
   messages. The progress mechanism is highly customizable, however, to
   suit the needs of applications that don't require this output, or that
   require the output to go somewhere other than STDERR or the console.

   The default progress routine is one that prints a message with a
   date/time stamp to STDERR if and only if STDERR is an interactive
   terminal, and otherwise is silent.

   You could write a custom progress routine that does something else or
   something in addition (e.g. logs to a file or syslog). The custom
   routine could either be implemented by overriding the progress_default()
   method in a subclass, or by calling progress_set() in any instance.

   The custom progress routine, if any, is stored in the _Progress
   parameter of the object. But use progress_set() and progress_get() to
   access it.

   The interface for your custom progress routine should be:

           sub MyProgress {my ($Obj, $Message) = @_; chomp $Message; .....}

   In other words, the routine takes a single message which may or may not
   have a trailing newline. It should always chomp the newline if present,
   and then do its business... which generally will include printing or
   logging a message (usually with a newline added).

   The default, built-in progress routine for Data::CTable is:

           sub progress_default
           {
               my ($this, $msg) = @_;
               chomp $msg;

               print STDERR (localtime() . " $msg\n") if -t STDERR;

               return(1);   ## Indicate progress actually completed
           }

   Of course, you are free to call this method directly at any time, and it
   will do its thing regardless of other progress-enabling settings. But
   the preferred way is to first set the settings and then call progress().

   The warn() method always calls progress_default() -- i.e. warnings will
   display even if progress is otherwise disabled or overridden at the
   object or class level. However, you could create a subclass that changes
   warn()'s behavior if desired. (For example, it could just call perl's
   builtin warn function, or be even more forceful, generating warnings
   even if STDERR is not a terminal, for example.)

   The progress_set() method may be used to override the progress routine
   for an individual object (set to 1/true for default behavior, or
   0/undef/false to disable progress for that object entirely).

   Call progress_class() to set similar values to control the global
   default behavior (e.g. turning on/off default progress behavior for all
   instances), but be cautious about using this approach in any environment
   where other programs might be accessing the same loaded class data,
   since the setting is stored in a class-owned global
   ($Data::CTable::DefaultProgress).

   Manipulating the class-default settings is only recommended in batch or
   shell-script environments, not in mod_perl Web applications where the
   module stays loaded into the Perl environment across multiple
   invocations, for example.

   If you want a particular method (e.g. read() but not write()) to be
   silent, you could make a subclass and could override that method with an
   implementation that first disables progress, calls the SUPER:: method,
   and then restores the progress setting to its original setting.

 Timed progress

   Timed progress is a way of printing periodically-recurring progress
   messages about potentially time-consuming processes to the terminal.

   For example, consider the following messages which might appear every 2
   seconds during a lengthy read() operation:

           Reading... 0 (0%)
           Reading... 2000 (4%)
           ...
           Reading... 38000 (96%)
           Reading... 40000 (100%)

   The progress_timed() method is called internally by potentially
   time-consuming processes (read(), write(), and sort()), and you may want
   to call it yourself from your own scripts, to produce
   weary-programmer-soothing visual output during otherwise panic-producing
   long delays.

   Generally, progress_timed() is called with the $Wait parameter set to
   true, which delays the display of any messages until 2 seconds have
   passed, so no messages will be displayed unless the process actually
   does end up being slower than 2 seconds.

   Parameters are:

           $Op    The string that identifies the "operation" taking place
           $Item  A milestone such as a number or datum to indicate progress
           $Pos   A numeric position against the (maybe estimated) baseline
           $Tot   The baseline.  If estimated, don't re-estimate too often
           $Wait  If true, skip printing the first message for this $Op

   All parameters except $Op are optional.

   progress_timed() has a throttle that keeps it from re-triggering more
   often than every 2 seconds for any given sequence of the same $Op. The
   clock is restarted each time you call it with a different $Op or $Tot
   from the previous call (on the assumption that if the operation or the
   baseline changes then that fact should be noted).

   The messages printed will start with "$Op... ".

   If you supply $Item, which could be a number or a string, the messages
   will then show the $Item after the $Op.

   If you supply BOTH $Pos and $Tot, then a percentage will be calculated
   and added to the readout; otherwise omitted.

   If you supply $Wait, the first message (only) that uses this $Op will be
   skipped, and the next one won't appear for at least 2 seconds.

   If using $Pos and $Tot to display percentages for your user, be sure to
   call progress_timed() one final time when $Pos == $Tot so your user sees
   the satisfying 100% milestone. This "completion" call will not be
   skipped even if 2 seconds have not passed since the previous timed
   progress message was printed.

   Althought progress_timed() is designed to cut down on too much visual
   output when called often in a tight loop, remember that it still takes
   some processing time to call it and so if you call it too frequently,
   you're slowing down the very loop you wish were running faster.

   So, you might want to call it every tenth or 100th or even 1000th time
   through a tight loop, instead of every time through, using the mod (%)
   operator:

           $t->progress_timed(....) if ($LoopCount % 100) == 0;

   progress_timed_default() is the method called internally by
   progress_timed() to actually print the messages it has prepared. In this
   implementation, progress_timed_default() just calls progress_default().
   That is, it ignores all other progress-inhibiting or -enhancing settings
   so delay-soothing messages will print on the terminal even if other
   messages are turned off.

   This is because the author assumes that even if you don't want all those
   other progress messages, you might still want these ones that explain
   long delays. If you REALLY don't, then just make yourself a lightweight
   subclass where progress_timed_default() is a no-op, or maybe calls
   regular progress(). For example:

           BEGIN {package Data::CTable::Silent; use vars qw(@ISA);
                  @ISA=qw(Data::CTable); sub progress_timed_default{}}

           ## Later...
           my $t = Data::CTable::Silent->new(...);

Rejecting or reporting on groups of records and continuing
   Use utility methods omit_warn() and omit_note() to conditionally omit
   some records from a table and warn (or "note") if any were affected.

   Use select_extract() to do the same thing but without actually removing
   the extracted records from the table, and restoring the original
   selection before select_extract was called.

   If you supply a file name as the 4th argument, the omitted records will
   be extracted to a file for later reference.

   If you supply a message prefix as the 5th argument, a string other than
   "WARNING" or "Note" may be specified.

           # Reject with a progress message prefixed by "WARNING:"

           $t->omit_warn(FirstName => sub{!length($_)}, "First name is empty");

                   Mon Aug 23 08:24:15 2004 WARNING: Omitting 2 of 78243 records (now 78241): First name is empty.

           # Reject with a progress message prefixed by "Note:", with output to a file

           $t->omit_note(FirstName => sub{!length($_)}, "First name is empty", "empty.names.txt");

                   Mon Aug 23 08:24:15 2004 Note: Omitting 2 of 78243 records (now 78241): First name is empty.
                   Mon Aug 23 08:24:15 2004 Writing bad.firstname.txt...
                   Mon Aug 23 08:24:15 2004 Wrote   bad.firstname.txt.

           # Extract some items, leaving original selection intact

           $t->select_extract(FirstName => sub{!length($_)}, "First name is empty", "empty.names.txt");

                   Mon Aug 23 08:24:15 2004 Note: Extracting 2 of 78243 records: First name is empty.

DEBUGGING / DUMPING
           ## Print some debugging output...

           $t->out()             ## Pretty-print $t using Data::ShowTable

           $t->dump()            ## Dump $t using Data::Dumper
           $t->dump($x, $y)      ## Dump anything else using Data::Dumper

           ## Print some debugging output and then die.

           die $t->out()         ## Same but die afterwards.

           die $t->dump()        ## Same but die afterwards.
           die $t->dump($x, $y)  ## Same but die afterwards.

   These two methods can be very helpful in debugging your scripts.

   The out() method, which has many options, is described in complete
   detail in the section below titled "FORMATTED TABLES". In short, it
   prints a nicely-formatted diagram of $t, obeying the custom field list
   if any and custom selection if any.

   The dump() method uses the Data::Dumper module to call &Dumper() on the
   table itself (by default) and prints the result to STDERR. If you
   specify any number of other values, those will be dumped instead using a
   single call to &Dumper (rather than individually).

 Optional module dependencies

   These methods require the otherwise-optional modules shown here:

           out()       Data::ShowTable
           dump()      Data::Dumper

   You'll get a warning at runtime if you try to call either method without
   the appropriate module installed on your system.

MISCELLANEOUS UTILITY METHODS
   The following utilities are methods of the Data::CTable object. They may
   be called directly by clients, subclassed, or used by subclass
   implementations as needed.

           ## Get cache file path (all args optional: defaulted from $t)

           $f  = $t->prep_cache_file($FileName, $CacheExtension, $CacheSubDir)

           ## Verify all directories in a path, creating any needed ones.

           $ok = $t->verify_or_create_path($DirPath, $Sep)

           ## Testing readability / writeability of a proposed file

           $ok = $t->try_file_read ($Path); ## Opens for read; then closes
           $ok = $t->try_file_write($Path); ## Opens for write; then deletes

           ## Getting parameters from object with optional overrides

           $param = $t->getparam($Params, $Param)

   prep_cache_file() is the internal method used by both read() and write()
   to calculate the name of a cache file to be used for a given $FileName.

   It calculates the path to the cache file that corresponds to the given
   $FileName (which may be a bare file name, a relative path, or a partial
   path, as long as it obeys the current platform's path format rules). All
   arguments are optional and if absent (undef), will be defaulted from the
   corresponding parameters in $t.

   In addition to calculating the path and file name, it also prepends the
   "current directory" path if there was no path. Then it checks that all
   directories mentioned in the path actually exist. If not, it fails.
   Then, it checks that EITHER the file exists and is readable, OR it does
   not exist but would be writeable in that directory. If any of these
   directory creations or file checks fails, then undef is returned (and
   there would be no cache file).

   You may call it with no arguments on a file that has been read() to find
   the path to the cache file that may have been used and/or created, if
   any.

   You may call it with a file name that was written to, to see what the
   corresponding written cache file would be.

   For example:

           ## Get name of cache file used or created by read and delete it.

           $RCache = $t->prep_cache_file() and unlink($RCache);

           ## Cache on write() and get name of file and delete it.

           $Written = $t->write(_CacheOnWrite=>1, _FileName=>"Foo.txt");
           $WCache  = $t->prep_cache_file($Written) and unlink($WCache);

   verify_or_create_path() is the internal routine used by read(), write(),
   and the cache-writing logic, that makes sure a requested file path
   exists (by creating it if necessary and possible) before any file is
   written by this module.

   (If you don't like this module's tendency to try to create directories,
   make yourself a subclass in which this routine simply checks -d on its
   $Path argument and returns the result.)

   It must be called with a full or partial path TO A DIRECTORY, NOT A
   FILE. You may supply $Sep, a platform-appropriate separator character
   (which defaults correctly for the runtime platform if you don't).

   Returns true if the path verification and/or creation ultimately
   succeeded, false otherwise (meaning that, after this call, there is no
   such directory on the system and so you should not try to write a file
   there).

   try_file_read() and try_file_write() are the internal methods called by
   prep_cache_file() as well as by read() and write() to preflight proposed
   file reading and writing locations.

   try_file_read() opens a file for read and closes it again; returns true
   if the open was possible.

   try_file_write() opens a file for write and closes it again, deleting it
   if successful. Returns true if the open for write and the delete were
   successful. (Be aware that this call will actually delete any existing
   file by this name.)

   The reason that failure to delete causes try_file_write() to fail is
   that successful cacheing depends on the ability to delete cache files as
   well as create them or write to them. A file in a location that couldn't
   be deleted will not be used for cacheing.

   getparam() looks up a named parameter in a params hash if it exists
   there, otherwise looks it up in the object, thereby allowing $Params to
   shadow any parameters in $this.

   This internal routine is used by any methods that allow overriding of
   parameters in the object when using a named-parameter calling interface.
   It should be used by any subclasses that also wish to use a
   named-parameter calling convention. For example:

           my $this        = shift;
           my $Params      = (@_ == 1 ? {_FieldList => $_[0]} : {@_});

           my($FieldList, $Selection) = map {$this->getparam($Params, $_)}
           qw(_FieldList  _Selection);

GENERAL-PURPOSE UTILITY FUNCTIONS
   These general-purpose utility routines are defined in the Data::CTable
   module but are not method calls. You may optionally import them or call
   them by their fully-qualified name.

           use Data::CTable qw(
                               guess_endings
                               guess_delimiter
                               path_info
                               path_is_absolute
                               min
                               max
                               );

           ## File-format guessing

           my $E = &guess_endings($IOHandle) ## Guess txt file line endings
           my $D = &guess_delimiter($String) ## Tab if found, else comma

           ## Cross-platform file path analysis

           my $Info = path_info();   ## Hash: 3 of platform's path values:
           my ($Sep,                 ## ... path separator (  / on Unix)
               $Up,                  ## ... "up" component (../ on Unix)
               $Cur) =               ## ... curr. dir path ( ./ on Unix)
           @$Info{qw(sep up cur)};

           my $Abs = path_is_absolute($Path)  ## Check path type

           ## Our old favorites min and max

           $x = max($x, 0);          ## Should have been part of Perl...
           $x = min($x, 100);

   guess_endings() tries to figure out whether an open IO::File handle has
   DOS, Mac, or Unix file endings. It reads successively large blocks of
   the file until it either finds evidence of at least two separate line
   endings (of any type, but presumably they are the same), or until it
   reaches the end of the file. Then, it takes the resulting block and
   searches for the first qualifying line ending sequence it finds, if any.
   This sequence is then returned to the caller. If it returns undef, it
   was not able to find any evidence of line endings in the file.

   guess_delimiter() takes a string buffer and returns a "," unless it
   finds a tab character before the first comma in the $String, if any, in
   which case a tab is returned.

   path_info() returns a hash of three helpful strings for building and
   parsing paths on the current platform. Knows about Mac, Dos/Win, and
   otherwise defaults to Unix.

   path_is_absolute($Path) returns true if it thinks the given path string
   is an absolute path on the current platform.

IMPLEMENTATION LIMITATIONS
   Column (field) names must not start with underscore
       This object is implemented as a blessed hash reference. By
       convention, keys that do not start with underscore are data columns
       and the key is the field name. Keys that do start with underscore
       refer to parameters or other data structures stored in the object.

       Consequently, no field names may start with underscore. When a file
       is read from disk, any field names that DO start with underscores
       will have the leading underscores stripped off. Strange things could
       then occur if the field names are then no longer unique. For
       example, field "A" and "_A" in the data file would be treated as the
       single field "A" after the file was read.

   Field values are always read as strings
       Field values when written to a file are necessarily converted to
       strings. When read back in, they are read as strings, regardless of
       original format. The sole exception is the empty string which is
       read back in as undef for efficiency.

       An exception is when the _CacheOnWrite feature is used: field values
       stored internally as integers or other scalar types may be saved and
       later restored as such. However, you should not rely on this
       behavior.

   Undef vs. empty
       Empty field values are stored as "undef" for efficiency. This means
       that programs should generally not rely on any differences between
       "" and undef in field values. However, when working with large but
       sparse tables, programs should take care not to convert undef values
       to empty strings unnecessarily since the separate string objects
       consume considerably more memory than undef.

CONTRIBUTIONS
   Corrections, bug reports, bug fixes, or feature additions are
   encouraged. Please send additions or patches with a clear explanation of
   their purpose. Consider making additions in the form of a subclass if
   possible.

   I'm committed to bundling useful subclasses contributed by myself or
   others with this main distribution.

   So, if you've got a subclass of Data::CTable (which should have a name
   like Data::CTable::YourClassName) and you would like it included in the
   main distribution, please send it along with a test script and I'll
   review the code and add it (at my discretion).

   If you've got a module that uses, augments, or complements this one, let
   me know that, too, and I'll make appropriate mention of it.

SEE ALSO
   The Data::CTable home page:

           http://christhorman.com/projects/perl/Data-CTable/

   The implementation in CTable.pm.

   The test.pl script, other subclasses, and examples.

   The Data::ShowTable module.

   The Data::Table module by Yingyao Zhou & Guangzhou Zou.

   The perlref manual page.

AUTHOR
   Chris Thorman <[email protected]>

   Copyright (c) 1995-2002 Chris Thorman. All rights reserved.

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