perly.y Yacc grammar for perl
pl2pm A pl to pm translator
pod/Makefile Make pods into something else
+pod/PerlDoc/Functions.pm used by splitpod
+pod/buildtoc generate perltoc.pod
pod/perl.pod Top level perl man page
pod/perlbook.pod Book info
pod/perlbot.pod Object-oriented Bag o' Tricks
pod/perlstyle.pod Style info
pod/perlsub.pod Subroutine info
pod/perlsyn.pod Syntax info
+pod/perltoc.pod TOC info
pod/perltrap.pod Trap info
pod/perlvar.pod Variable info
pod/perlxs.pod XS api info
pod/pod2html.PL Precursor for translator to turn pod into HTML
pod/pod2latex.PL Precursor for translator to turn pod into LaTeX
pod/pod2man.PL Precursor for translator to turn pod into manpage
+pod/pod2text Precursor for translator to turn pod into text
+pod/roffitall troff the whole man page set
pod/splitman Splits perlfunc into multiple man pages
+pod/splitpod Splits perlfunc into multiple pod pages
pp.c Push/Pop code
pp.h Push/Pop code defs
pp_ctl.c Push/Pop code for control flow
untie @h ;
+=head2 Locking Databases
-=head1 CHANGES
+Concurrent access of a read-write database by several parties requires
+them all to use some kind of locking. Here's an example of Tom's that
+uses the I<fd> method to get the file descriptor, and then a careful
+open() to give something Perl will flock() for you. Run this repeatedly
+in the background to watch the locks granted in proper order.
-=head2 0.1
+ use Fcntl;
+ use DB_File;
+
+ use strict;
+
+ sub LOCK_SH { 1 }
+ sub LOCK_EX { 2 }
+ sub LOCK_NB { 4 }
+ sub LOCK_UN { 8 }
+
+ my($oldval, $fd, $db, %db, $value, $key);
+
+ $key = shift || 'default';
+ $value = shift || 'magic';
+
+ $value .= " $$";
+
+ $db = tie(%db, 'DB_File', '/tmp/foo.db', O_CREAT|O_RDWR, 0644)
+ || die "dbcreat /tmp/foo.db $!";
+ $fd = $db->fd;
+ print "$$: db fd is $fd\n";
+ open(DB_FH, "+<&=$fd") || die "dup $!";
+
+
+ unless (flock (DB_FH, LOCK_SH | LOCK_NB)) {
+ print "$$: CONTENTION; can't read during write update!
+ Waiting for read lock ($!) ....";
+ unless (flock (DB_FH, LOCK_SH)) { die "flock: $!" }
+ }
+ print "$$: Read lock granted\n";
+
+ $oldval = $db{$key};
+ print "$$: Old value was $oldval\n";
+ flock(DB_FH, LOCK_UN);
+
+ unless (flock (DB_FH, LOCK_EX | LOCK_NB)) {
+ print "$$: CONTENTION; must have exclusive lock!
+ Waiting for write lock ($!) ....";
+ unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }
+ }
+
+ print "$$: Write lock granted\n";
+ $db{$key} = $value;
+ sleep 10;
+
+ flock(DB_FH, LOCK_UN);
+ untie %db;
+ close(DB_FH);
+ print "$$: Updated db to $key=$value\n";
+
+=head1 HISTORY
+
+=over
+
+=item 0.1
First Release.
-=head2 0.2
+=item 0.2
When B<DB_File> is opening a database file it no longer terminates the
process if I<dbopen> returned an error. This allows file protection
errors to be caught at run time. Thanks to Judith Grass
-<grass@cybercash.com> for spotting the bug.
+E<lt>grass@cybercash.comE<gt> for spotting the bug.
-=head2 0.3
+=item 0.3
Added prototype support for multiple btree compare callbacks.
-=head2 1.0
+=item 1.0
B<DB_File> has been in use for over a year. To reflect that, the
version number has been incremented to 1.0.
Using the I<push> method on an empty list didn't work properly. This
has been fixed.
-=head2 1.01
+=item 1.01
Fixed a core dump problem with SunOS.
=head1 AVAILABILITY
-Berkeley DB is available via the hold C<ftp.cs.berkeley.edu> in the
-directory C</ucb/4bsd/db.tar.gz>. It is I<not> under the GPL.
+Berkeley DB is available at your nearest CPAN archive (see
+L<perlmod/"CPAN"> for a list) in F<src/misc/db.1.85.tar.gz>, or via the
+host F<ftp.cs.berkeley.edu> in F</ucb/4bsd/db.tar.gz>. It is I<not> under
+the GPL.
=head1 SEE ALSO
}
sub wait {
- usage "wait(statusvariable)" if @_ != 1;
- local $result = wait();
- $_[0] = $?;
- $result;
+ usage "wait()" if @_ != 0;
+ wait();
}
sub waitpid {
- usage "waitpid(pid, statusvariable, options)" if @_ != 3;
- local $result = waitpid($_[0], $_[2]);
- $_[1] = $?;
- $result;
+ usage "waitpid(pid, options)" if @_ != 2;
+ waitpid($_[0], $_[1]);
}
sub gmtime {
POSIX - Perl interface to IEEE Std 1003.1
+=head1 SYNOPSIS
+
+ use POSIX;
+ use POSIX qw(setsid);
+ use POSIX qw(:errno_h :fcntl_h);
+
+ printf "EINTR is %d\n", EINTR;
+
+ $sess_id = POSIX::setsid();
+
+ $fd = POSIX::open($path, O_CREAT|O_EXCL|O_WRONLY, 0644);
+ # note: that's a filedescriptor, *NOT* a filehandle
+
=head1 DESCRIPTION
The POSIX module permits you to access all (or nearly all) the standard
constants and macros in an organization which roughly follows IEEE Std
1003.1b-1993.
-=head1 EXAMPLES
-
- printf "EINTR is %d\n", EINTR;
-
- $sess_id = POSIX::setsid();
-
- $fd = POSIX::open($path, O_CREAT|O_EXCL|O_WRONLY, 0644);
- # note: that's a filedescriptor, *NOT* a filehandle
-
=head1 NOTE
The POSIX module is probably the most complex Perl module supplied with
=item assert
+Unimplemented.
=item atan
=item close
+Close the file. This uses file descriptors such as those obtained by calling
+C<POSIX::open>.
+
+ $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+ POSIX::close( $fd );
Returns C<undef> on failure.
=item creat
+Create a new file. This returns a file descriptor like the ones returned by
+C<POSIX::open>. Use C<POSIX::close> to close the file.
+
+ $fd = POSIX::creat( "foo", 0611 );
+ POSIX::close( $fd );
=item ctermid
-Generates the path name for controlling terminal.
+Generates the path name for the controlling terminal.
$path = POSIX::ctermid();
=item dup
+This is similar to the C function C<dup()>.
+
+This uses file descriptors such as those obtained by calling
+C<POSIX::open>.
Returns C<undef> on failure.
=item dup2
+This is similar to the C function C<dup2()>.
+
+This uses file descriptors such as those obtained by calling
+C<POSIX::open>.
Returns C<undef> on failure.
=item fpathconf
+Retrieves the value of a configurable limit on a file or directory. This
+uses file descriptors such as those obtained by calling C<POSIX::open>.
+
+The following will determine the maximum length of the longest allowable
+pathname on the filesystem which holds C</tmp/foo>.
+
+ $fd = POSIX::open( "/tmp/foo", &POSIX::O_RDONLY );
+ $path_max = POSIX::fpathconf( $fd, &POSIX::_PC_PATH_MAX );
Returns C<undef> on failure.
=item frexp
+Return the mantissa and exponent of a floating-point number.
+
+ ($mantissa, $exponent) = POSIX::frexp( 3.14 );
=item fscanf
=item fstat
+Get file status. This uses file descriptors such as those obtained by
+calling C<POSIX::open>. The data returned is identical to the data from
+Perl's builtin C<stat> function.
+
+ $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+ @stats = POSIX::fstat( $fd );
=item ftell
=item isalnum
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isalpha
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isatty
=item iscntrl
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isdigit
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isgraph
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item islower
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isprint
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item ispunct
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isspace
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isupper
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item isxdigit
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
=item kill
=item localeconv
+Get numeric formatting information. Returns a reference to a hash
+containing the current locale formatting values.
+
+The database for the B<de> (Deutsch or German) locale.
+
+ $loc = POSIX::setlocale( &POSIX::LC_ALL, "de" );
+ print "Locale = $loc\n";
+ $lconv = POSIX::localeconv();
+ print "decimal_point = ", $lconv->{decimal_point}, "\n";
+ print "thousands_sep = ", $lconv->{thousands_sep}, "\n";
+ print "grouping = ", $lconv->{grouping}, "\n";
+ print "int_curr_symbol = ", $lconv->{int_curr_symbol}, "\n";
+ print "currency_symbol = ", $lconv->{currency_symbol}, "\n";
+ print "mon_decimal_point = ", $lconv->{mon_decimal_point}, "\n";
+ print "mon_thousands_sep = ", $lconv->{mon_thousands_sep}, "\n";
+ print "mon_grouping = ", $lconv->{mon_grouping}, "\n";
+ print "positive_sign = ", $lconv->{positive_sign}, "\n";
+ print "negative_sign = ", $lconv->{negative_sign}, "\n";
+ print "int_frac_digits = ", $lconv->{int_frac_digits}, "\n";
+ print "frac_digits = ", $lconv->{frac_digits}, "\n";
+ print "p_cs_precedes = ", $lconv->{p_cs_precedes}, "\n";
+ print "p_sep_by_space = ", $lconv->{p_sep_by_space}, "\n";
+ print "n_cs_precedes = ", $lconv->{n_cs_precedes}, "\n";
+ print "n_sep_by_space = ", $lconv->{n_sep_by_space}, "\n";
+ print "p_sign_posn = ", $lconv->{p_sign_posn}, "\n";
+ print "n_sign_posn = ", $lconv->{n_sign_posn}, "\n";
=item localtime
=item lseek
+Move the read/write file pointer. This uses file descriptors such as
+those obtained by calling C<POSIX::open>.
+
+ $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+ $off_t = POSIX::lseek( $fd, 0, &POSIX::SEEK_SET );
Returns C<undef> on failure.
=item mblen
+This is identical to the C function C<mblen()>.
=item mbstowcs
+This is identical to the C function C<mbstowcs()>.
=item mbtowc
+This is identical to the C function C<mbtowc()>.
=item memchr
=item mkfifo
+This is similar to the C function C<mkfifo()>.
Returns C<undef> on failure.
=item mktime
+Convert date/time info to a calendar time.
+
+Synopsis:
+
+ mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
+
+The month (C<mon>), weekday (C<wday>), and yearday (C<yday>) begin at zero.
+I.e. January is 0, not 1; Sunday is 0, not 1; January 1st is 0, not 1. The
+year (C<year>) is given in years since 1900. I.e. The year 1995 is 95; the
+year 2001 is 101. Consult your system's C<mktime()> manpage for details
+about these and the other arguments.
+
+Calendar time for December 12, 1995, at 10:30 am.
+
+ $time_t = POSIX::mktime( 0, 30, 10, 12, 11, 95 );
+ print "Date = ", POSIX::ctime($time_t);
Returns C<undef> on failure.
=item modf
+Return the integral and fractional parts of a floating-point number.
+
+ ($fractional, $integral) = POSIX::modf( 3.14 );
=item nice
+This is similar to the C function C<nice()>.
Returns C<undef> on failure.
=item open
+Open a file for reading for writing. This returns file descriptors, not
+Perl filehandles. Use C<POSIX::close> to close the file.
+
+Open a file read-only with mode 0666.
+
+ $fd = POSIX::open( "foo" );
+
+Open a file for read and write.
+
+ $fd = POSIX::open( "foo", &POSIX::O_RDWR );
+
+Open a file for write, with truncation.
+
+ $fd = POSIX::open( "foo", &POSIX::O_WRONLY | &POSIX::O_TRUNC );
+
+Create a new file with mode 0640. Set up the file for writing.
+
+ $fd = POSIX::open( "foo", &POSIX::O_CREAT | &POSIX::O_WRONLY, 0640 );
Returns C<undef> on failure.
=item opendir
+Open a directory for reading.
+
+ $dir = POSIX::opendir( "/tmp" );
+ @files = POSIX::readdir( $dir );
+ POSIX::closedir( $dir );
+
+Returns C<undef> on failure.
=item pathconf
=item pipe
+Create an interprocess channel. This returns file descriptors like those
+returned by C<POSIX::open>.
+
+ ($fd0, $fd1) = POSIX::pipe();
+ POSIX::write( $fd0, "hello", 5 );
+ POSIX::read( $fd1, $buf, 5 );
=item pow
=item read
+Read from a file. This uses file descriptors such as those obtained by
+calling C<POSIX::open>. If the buffer C<$buf> is not large enough for the
+read then Perl will extend it to make room for the request.
+
+ $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+ $bytes = POSIX::read( $fd, $buf, 3 );
Returns C<undef> on failure.
=item setpgid
+This is similar to the C function C<setpgid()>.
Returns C<undef> on failure.
=item sigaction
+Detailed signal management. This uses C<POSIX::SigAction> objects for the
+C<action> and C<oldaction> arguments. Consult your system's C<sigaction>
+manpage for details.
+
+Synopsis:
+
+ sigaction(sig, action, oldaction = 0)
Returns C<undef> on failure.
=item sigpending
+Examine signals that are blocked and pending. This uses C<POSIX::SigSet>
+objects for the C<sigset> argument. Consult your system's C<sigpending>
+manpage for details.
+
+Synopsis:
+
+ sigpending(sigset)
Returns C<undef> on failure.
=item sigprocmask
+Change and/or examine calling process's signal mask. This uses
+C<POSIX::SigSet> objects for the C<sigset> and C<oldsigset> arguments.
+Consult your system's C<sigprocmask> manpage for details.
+
+Synopsis:
+
+ sigprocmask(how, sigset, oldsigset = 0)
Returns C<undef> on failure.
=item sigsuspend
+Install a signal mask and suspend process until signal arrives. This uses
+C<POSIX::SigSet> objects for the C<signal_mask> argument. Consult your
+system's C<sigsuspend> manpage for details.
+
+Synopsis:
+
+ sigsuspend(signal_mask)
Returns C<undef> on failure.
=item sprintf
+This is identical to Perl's builtin C<sprintf()> function.
=item sqrt
=item strftime
+Convert date and time information to string. Returns the string.
+
+Synopsis:
+
+ strftime(fmt, sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
+
+The month (C<mon>), weekday (C<wday>), and yearday (C<yday>) begin at zero.
+I.e. January is 0, not 1; Sunday is 0, not 1; January 1st is 0, not 1. The
+year (C<year>) is given in years since 1900. I.e. The year 1995 is 95; the
+year 2001 is 101. Consult your system's C<strftime()> manpage for details
+about these and the other arguments.
+
+The string for Tuesday, December 12, 1995.
+
+ $str = POSIX::strftime( "%A, %B %d, %Y", 0, 0, 0, 12, 11, 95, 2 );
+ print "$str\n";
=item strlen
=item strxfrm
+String transformation. Returns the transformed string.
+
+ $dst = POSIX::strxfrm( $src );
=item sysconf
=item tcdrain
+This is similar to the C function C<tcdrain()>.
Returns C<undef> on failure.
=item tcflow
+This is similar to the C function C<tcflow()>.
Returns C<undef> on failure.
=item tcflush
+This is similar to the C function C<tcflush()>.
Returns C<undef> on failure.
=item tcsendbreak
+This is similar to the C function C<tcsendbreak()>.
Returns C<undef> on failure.
=item tcsetpgrp
+This is similar to the C function C<tcsetpgrp()>.
Returns C<undef> on failure.
=item ttyname
+This is identical to the C function C<ttyname()>.
=item tzname
+Retrieves the time conversion information from the C<tzname> variable.
+
+ POSIX::tzset();
+ ($std, $dst) = POSIX::tzname();
=item tzset
=item uname
+Get name of current operating system.
+
+ ($sysname, $nodename, $release, $version, $machine ) = POSIX::uname();
=item ungetc
=item wait
+This is identical to Perl's builtin C<wait()> function.
=item waitpid
+Wait for a child process to change state. This is identical to Perl's
+builtin C<waitpid()> function.
+
+ $pid = POSIX::waitpid( -1, &POSIX::WNOHANG );
+ print "status = ", ($? / 256), "\n";
=item wcstombs
+This is identical to the C function C<wcstombs()>.
=item wctomb
+This is identical to the C function C<wctomb()>.
=item write
+Write to a file. This uses file descriptors such as those obtained by
+calling C<POSIX::open>.
+
+ $fd = POSIX::open( "foo", &POSIX::O_WRONLY );
+ $buf = "hello";
+ $bytes = POSIX::write( $b, $buf, 5 );
Returns C<undef> on failure.
=item new
+Open a file and return a Perl filehandle. The first parameter is the
+filename and the second parameter is the mode. The mode should be specified
+as C<a> for append, C<w> for write, and E<lt> or C<""> for read.
+
+Open a file for reading.
+
+ $fh = FileHandle->new( "foo", "" );
+ die "Unable to open foo for reading" unless $fh;
+
+Open a file for writing.
+
+ $fh = FileHandle->new( "foo", "w" );
+ die "Unable to open foo for writing" unless $fh;
+
+Use C<FileHandle::close()> to close the file or let the FileHandle object's
+destructor perform the close.
=item clearerr
+Resets the error indicator and EOF indicator to zero.
+
+ $fh->clearerr;
=item close
+Close the file.
+
+ $fh->close;
=item eof
+Tests for end of file.
+
+ if( $fh->eof ){
+ print "end of file\n";
+ }
=item error
+Returns non-zero if there has been an error while reading or writing a file.
+
+ if( $fh->error ){
+ print "error\n";
+ }
=item fileno
+Returns the integer file descriptor associated with the file.
+
+ $fileno = $fh->fileno;
=item flush
+Flush the stream.
+
+ $fh->flush;
Returns C<undef> on failure.
=item getc
+Get a character from the stream.
+
+ $ch = $fh->getc;
=item getpos
+Retrieve the file pointer position. The returned value can be used as an
+argument to C<setpos()>.
+
+ $pos = $fh->getpos;
=item gets
+Retrieve a line from the open file.
+
+ $line = $fh->gets;
=item new_from_fd
+Open a file using a file descriptor. Return a Perl filehandle. The first
+parameter should be a file descriptor, which can come from C<POSIX::open()>.
+The second parameter, the mode, should be C<a> for append, C<w> for write,
+and E<lt> or C<""> for read. The mode should match the mode which was used
+when the file descriptor was created.
+
+ $fd = POSIX::open( "typemap" );
+ $fh = FileHandle->new_from_fd( $fd, "<" );
+ die "FileHandle failed" unless $fh;
=item new_tmpfile
+Creates a temporary file, opens it for writing, and returns a Perl
+filehandle. Consult your system's C<tmpfile()> manpage for details.
+
+ $fh = FileHandle->new_tmpfile;
+ die "FileHandle failed" unless $fh;
=item seek
+Reposition file pointer.
+
+ $fh->seek( 2, &POSIX::SEEK_SET );
=item setbuf
=item setpos
+Set the file pointer position.
+
+ $pos = $fh->getpos;
+ $fh->setpos( $pos );
Returns C<undef> on failure.
=item tell
+Returns the current file position, in bytes.
+
+ $pos = $fh->tell;
=item ungetc
=item new
-Creates a new SigAction object. This object will be destroyed automatically
-when it is no longer needed.
+Creates a new C<POSIX::SigAction> object which corresponds to the C
+C<struct sigaction>. This object will be destroyed automatically when it is
+no longer needed. The first parameter is the fully-qualified name of a sub
+which is a signal-handler. The second parameter is a C<POSIX::SigSet>
+object. The third parameter contains the C<sa_flags>.
+
+ $sigset = POSIX::SigSet->new;
+ $sigaction = POSIX::SigAction->new( 'main::handler', $sigset, &POSIX::SA_NOCLDSTOP );
+
+This C<POSIX::SigAction> object should be used with the C<POSIX::sigaction()>
+function.
=back
=item getattr
+Get terminal control attributes.
+
+Obtain the attributes for stdin.
+
+ $termios->getattr()
+
+Obtain the attributes for stdout.
+
+ $termios->getattr( 1 )
Returns C<undef> on failure.
=item setattr
+Set terminal control attributes.
+
+Set attributes immediately for stdout.
+
+ $termios->setattr( 1, &POSIX::TCSANOW );
Returns C<undef> on failure.
=head1 CREATION
-This document generated by mkposixman.PL version 951129.
+This document generated by ./mkposixman.PL version 19951212.
--- /dev/null
+use ExtUtils::MakeMaker;
+WriteMakefile();
--- /dev/null
+package Safe;
+require Exporter;
+require DynaLoader;
+use Carp;
+@ISA = qw(Exporter DynaLoader);
+@EXPORT_OK = qw(op_mask ops_to_mask mask_to_ops opcode opname
+ MAXO emptymask fullmask);
+
+=head1 NAME
+
+Safe - Safe extension module for Perl
+
+=head1 DESCRIPTION
+
+The Safe extension module allows the creation of compartments
+in which perl code can be evaluated. Each compartment has
+
+=over 8
+
+=item a new namespace
+
+The "root" of the namespace (i.e. "main::") is changed to a
+different package and code evaluated in the compartment cannot
+refer to variables outside this namespace, even with run-time
+glob lookups and other tricks. Code which is compiled outside
+the compartment can choose to place variables into (or share
+variables with) the compartment's namespace and only that
+data will be visible to code evaluated in the compartment.
+
+By default, the only variables shared with compartments are the
+"underscore" variables $_ and @_ (and, technically, the much less
+frequently used %_, the _ filehandle and so on). This is because
+otherwise perl operators which default to $_ will not work and neither
+will the assignment of arguments to @_ on subroutine entry.
+
+=item an operator mask
+
+Each compartment has an associated "operator mask". Recall that
+perl code is compiled into an internal format before execution.
+Evaluating perl code (e.g. via "eval" or "do 'file'") causes
+the code to be compiled into an internal format and then,
+provided there was no error in the compilation, executed.
+Code evaulated in a compartment compiles subject to the
+compartment's operator mask. Attempting to evaulate code in a
+compartment which contains a masked operator will cause the
+compilation to fail with an error. The code will not be executed.
+
+By default, the operator mask for a newly created compartment masks
+out all operations which give "access to the system" in some sense.
+This includes masking off operators such as I<system>, I<open>,
+I<chown>, and I<shmget> but does not mask off operators such as
+I<print>, I<sysread> and I<E<lt>HANDLE<gt>>. Those file operators
+are allowed since for the code in the compartment to have access
+to a filehandle, the code outside the compartment must have explicitly
+placed the filehandle variable inside the compartment.
+
+Since it is only at the compilation stage that the operator mask
+applies, controlled access to potentially unsafe operations can
+be achieved by having a handle to a wrapper subroutine (written
+outside the compartment) placed into the compartment. For example,
+
+ $cpt = new Safe;
+ sub wrapper {
+ # vet arguments and perform potentially unsafe operations
+ }
+ $cpt->share('&wrapper');
+
+=back
+
+=head2 Operator masks
+
+An operator mask exists at user-level as a string of bytes of length
+MAXO, each of which is either 0x00 or 0x01. Here, MAXO is the number
+of operators in the current version of perl. The subroutine MAXO()
+(available for export by package Safe) returns the number of operators
+in the current version of perl. Note that, unlike the beta versions of
+the Safe extension, this is a reliable count of the number of
+operators in the currently running perl executable. The presence of a
+0x01 byte at offset B<n> of the string indicates that operator number
+B<n> should be masked (i.e. disallowed). The Safe extension makes
+available routines for converting from operator names to operator
+numbers (and I<vice versa>) and for converting from a list of operator
+names to the corresponding mask (and I<vice versa>).
+
+=head2 Methods in class Safe
+
+To create a new compartment, use
+
+ $cpt = new Safe;
+
+Optional arguments are (NAMESPACE, MASK), where
+
+=over 8
+
+=item NAMESPACE
+
+is the root namespace to use for the compartment (defaults to
+"Safe::Root000000000", auto-incremented for each new compartment); and
+
+=item MASK
+
+is the operator mask to use (defaults to a fairly restrictive set).
+
+=back
+
+The following methods can then be used on the compartment
+object returned by the above constructor. The object argument
+is implicit in each case.
+
+=over 8
+
+=item root (NAMESPACE)
+
+This is a get-or-set method for the compartment's namespace. With the
+NAMESPACE argument present, it sets the root namespace for the
+compartment. With no NAMESPACE argument present, it returns the
+current root namespace of the compartment.
+
+=item mask (MASK)
+
+This is a get-or-set method for the compartment's operator mask.
+With the MASK argument present, it sets the operator mask for the
+compartment. With no MASK argument present, it returns the
+current operator mask of the compartment.
+
+=item trap (OP, ...)
+
+This sets bits in the compartment's operator mask corresponding
+to each operator named in the list of arguments. Each OP can be
+either the name of an operation or its number. See opcode.h or
+opcode.pl in the main perl distribution for a canonical list of
+operator names.
+
+=item untrap (OP, ...)
+
+This resets bits in the compartment's operator mask corresponding
+to each operator named in the list of arguments. Each OP can be
+either the name of an operation or its number. See opcode.h or
+opcode.pl in the main perl distribution for a canonical list of
+operator names.
+
+=item share (VARNAME, ...)
+
+This shares the variable(s) in the argument list with the compartment.
+Each VARNAME must be the B<name> of a variable with a leading type
+identifier included. Examples of legal variable names are '$foo' for
+a scalar, '@foo' for an array, '%foo' for a hash, '&foo' for a
+subroutine and '*foo' for a glob (i.e. all symbol table entries
+associated with "foo", including scalar, array, hash, sub and filehandle).
+
+=item varglob (VARNAME)
+
+This returns a glob for the symbol table entry of VARNAME in the package
+of the compartment. VARNAME must be the B<name> of a variable without
+any leading type marker. For example,
+
+ $cpt = new Safe 'Root';
+ $Root::foo = "Hello world";
+ # Equivalent version which doesn't need to know $cpt's package name:
+ ${$cpt->varglob('foo')} = "Hello world";
+
+
+=item reval (STRING)
+
+This evaluates STRING as perl code inside the compartment. The code
+can only see the compartment's namespace (as returned by the B<root>
+method). Any attempt by code in STRING to use an operator which is
+in the compartment's mask will cause an error (at run-time of the
+main program but at compile-time for the code in STRING). The error
+is of the form "%s trapped by operation mask operation...". If an
+operation is trapped in this way, then the code in STRING will not
+be executed. If such a trapped operation occurs or any other
+compile-time or return error, then $@ is set to the error message,
+just as with an eval(). If there is no error, then the method returns
+the value of the last expression evaluated, or a return statement may
+be used, just as with subroutines and B<eval()>. Note that this
+behaviour differs from the beta distribution of the Safe extension
+where earlier versions of perl made it hard to mimic the return
+behaviour of the eval() command.
+
+=item rdo (FILENAME)
+
+This evaluates the contents of file FILENAME inside the compartment.
+See above documentation on the B<reval> method for further details.
+
+=back
+
+=head2 Subroutines in package Safe
+
+The Safe package contains subroutines for manipulating operator
+names and operator masks. All are available for export by the package.
+The canonical list of operator names is the contents of the array
+op_name defined and initialised in file F<opcode.h> of the Perl
+source distribution.
+
+=over 8
+
+=item ops_to_mask (OP, ...)
+
+This takes a list of operator names and returns an operator mask
+with precisely those operators masked.
+
+=item mask_to_ops (MASK)
+
+This takes an operator mask and returns a list of operator names
+corresponding to those operators which are masked in MASK.
+
+=item opcode (OP, ...)
+
+This takes a list of operator names and returns the corresponding
+list of opcodes (which can then be used as byte offsets into a mask).
+
+=item opname (OP, ...)
+
+This takes a list of opcodes and returns the corresponding list of
+operator names.
+
+=item fullmask
+
+This just returns a mask which has all operators masked.
+It returns the string "\1" x MAXO().
+
+=item emptymask
+
+This just returns a mask which has all operators unmasked.
+It returns the string "\0" x MAXO(). This is useful if you
+want a compartment to make use of the namespace protection
+features but do not want the default restrictive mask.
+
+=item MAXO
+
+This returns the number of operators (and hence the length of an
+operator mask). Note that, unlike the beta distributions of the
+Safe extension, this is derived from a genuine integer variable
+in the perl executable and not from a preprocessor constant.
+This means that the Safe extension is more robust in the presence
+of mismatched versions of the perl executable and the Safe extension.
+
+=item op_mask
+
+This returns the operator mask which is actually in effect at the
+time the invocation to the subroutine is compiled. In general,
+this is probably not terribly useful.
+
+=back
+
+=head2 AUTHOR
+
+Malcolm Beattie, mbeattie@sable.ox.ac.uk.
+
+=cut
+
+my $safes = "1111111111111111111111101111111111111111111111111111111111111111"
+ . "1111111111111111111111111111111111111111111111111111111111111111"
+ . "1111110011111111111011111111111111111111111111111111111101001010"
+ . "0110111111111111111111110011111111100001000000000000000000000100"
+ . "0000000000000111110000001111111110100000000000001111111111111111"
+ . "11111111111111111110";
+
+my $default_root = 'Safe::Root000000000';
+
+sub new {
+ my($class, $root, $mask) = @_;
+ my $obj = {};
+ bless $obj, $class;
+ $obj->root(defined($root) ? $root : $default_root++);
+ $obj->mask(defined($mask) ? $mask : $default_mask);
+ # We must share $_ and @_ with the compartment or else ops such
+ # as split, length and so on won't default to $_ properly, nor
+ # will passing argument to subroutines work (via @_). In fact,
+ # for reasons I don't completely understand, we need to share
+ # the whole glob *_ rather than $_ and @_ separately, otherwise
+ # @_ in non default packages within the compartment don't work.
+ *{$obj->root . "::_"} = *_;
+ return $obj;
+}
+
+sub root {
+ my $obj = shift;
+ if (@_) {
+ $obj->{Root} = $_[0];
+ } else {
+ return $obj->{Root};
+ }
+}
+
+sub mask {
+ my $obj = shift;
+ if (@_) {
+ $obj->{Mask} = verify_mask($_[0]);
+ } else {
+ return $obj->{Mask};
+ }
+}
+
+sub verify_mask {
+ my($mask) = @_;
+ if (length($mask) != MAXO() || $mask !~ /^[\0\1]+$/) {
+ croak("argument is not a mask");
+ }
+ return $mask;
+}
+
+sub trap {
+ my $obj = shift;
+ $obj->setmaskel("\1", @_);
+}
+
+sub untrap {
+ my $obj = shift;
+ $obj->setmaskel("\0", @_);
+}
+
+sub emptymask { "\0" x MAXO() }
+sub fullmask { "\1" x MAXO() }
+
+sub setmaskel {
+ my $obj = shift;
+ my $val = shift;
+ croak("bad value for mask element") unless $val eq "\0" || $val eq "\1";
+ my $maskref = \$obj->{Mask};
+ my ($op, $opcode);
+ foreach $op (@_) {
+ $opcode = ($op =~ /^\d/) ? $op : opcode($op);
+ substr($$maskref, $opcode, 1) = $val;
+ }
+}
+
+sub share {
+ my $obj = shift;
+ my $root = $obj->root();
+ my ($arg);
+ foreach $arg (@_) {
+ my $var;
+ ($var = $arg) =~ s/^(.)//;
+ my $caller = caller;
+ *{$root."::$var"} = ($1 eq '$') ? \${$caller."::$var"}
+ : ($1 eq '@') ? \@{$caller."::$var"}
+ : ($1 eq '%') ? \%{$caller."::$var"}
+ : ($1 eq '*') ? *{$caller."::$var"}
+ : ($1 eq '&') ? \&{$caller."::$var"}
+ : croak(qq(No such variable type for "$1$var"));
+ }
+}
+
+sub varglob {
+ my ($obj, $var) = @_;
+ return *{$obj->root()."::$var"};
+}
+
+sub reval {
+ my ($obj, $expr) = @_;
+ my $root = $obj->{Root};
+ my $mask = $obj->{Mask};
+ verify_mask($mask);
+
+ my $evalsub = eval sprintf(<<'EOT', $root);
+ package %s;
+ sub {
+ eval $expr;
+ }
+EOT
+ return safe_call_sv($root, $mask, $evalsub);
+}
+
+sub rdo {
+ my ($obj, $file) = @_;
+ my $root = $obj->{Root};
+ my $mask = $obj->{Mask};
+ verify_mask($mask);
+
+ $file =~ s/"/\\"/g; # just in case the filename contains any double quotes
+ my $evalsub = eval sprintf(<<'EOT', $root, $file);
+ package %s;
+ sub {
+ do "%s";
+ }
+EOT
+ return safe_call_sv($root, $mask, $evalsub);
+}
+
+bootstrap Safe;
+
+$safes .= "0" x (MAXO() - length($safes));
+($default_mask = $safes) =~ tr/01/\1\0/; # invert for mask
+
+1;
--- /dev/null
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+MODULE = Safe PACKAGE = Safe
+
+void
+safe_call_sv(package, mask, codesv)
+ char * package
+ SV * mask
+ SV * codesv
+ CODE:
+ int i;
+ char *str;
+ STRLEN len;
+
+ ENTER;
+ SAVETMPS;
+ save_hptr(&defstash);
+ save_aptr(&endav);
+ SAVEPPTR(op_mask);
+ Newz(666, op_mask, maxo, char);
+ SAVEFREEPV(op_mask);
+ str = SvPV(mask, len);
+ if (maxo != len)
+ croak("Bad mask length");
+ for (i = 0; i < maxo; i++)
+ op_mask[i] = str[i];
+ defstash = gv_stashpv(package, TRUE);
+ endav = (AV*)sv_2mortal((SV*)newAV()); /* Ignore END blocks for now */
+ GvHV(gv_fetchpv("main::", TRUE, SVt_PVHV)) = defstash;
+ PUSHMARK(sp);
+ i = perl_call_sv(codesv, G_SCALAR|G_EVAL|G_KEEPERR);
+ SPAGAIN;
+ ST(0) = i ? newSVsv(POPs) : &sv_undef;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ sv_2mortal(ST(0));
+
+void
+op_mask()
+ CODE:
+ ST(0) = sv_newmortal();
+ if (op_mask)
+ sv_setpvn(ST(0), op_mask, maxo);
+
+void
+mask_to_ops(mask)
+ SV * mask
+ PPCODE:
+ STRLEN len;
+ char *maskstr = SvPV(mask, len);
+ int i;
+ if (maxo != len)
+ croak("Bad mask length");
+ for (i = 0; i < maxo; i++)
+ if (maskstr[i])
+ XPUSHs(sv_2mortal(newSVpv(op_name[i], 0)));
+
+void
+ops_to_mask(...)
+ CODE:
+ int i, j;
+ char *mask, *op;
+ Newz(666, mask, maxo, char);
+ for (i = 0; i < items; i++)
+ {
+ op = SvPV(ST(i), na);
+ for (j = 0; j < maxo && strNE(op, op_name[j]); j++) /* nothing */ ;
+ if (j < maxo)
+ mask[j] = 1;
+ else
+ {
+ Safefree(mask);
+ croak("bad op name \"%s\" in mask", op);
+ }
+ }
+ ST(0) = sv_newmortal();
+ sv_usepvn(ST(0), mask, maxo);
+
+void
+opname(...)
+ PPCODE:
+ int i, opcode;
+ for (i = 0; i < items; i++)
+ {
+ opcode = SvIV(ST(i));
+ if (opcode < 0 || opcode >= maxo)
+ croak("opcode out of range");
+ XPUSHs(sv_2mortal(newSVpv(op_name[opcode], 0)));
+ }
+
+void
+opcode(...)
+ PPCODE:
+ int i, j;
+ char *op;
+ for (i = 0; i < items; i++)
+ {
+ op = SvPV(ST(i), na);
+ for (j = 0; j < maxo && strNE(op, op_name[j]); j++) /* nothing */ ;
+ if (j == maxo)
+ croak("bad op name \"%s\"", op);
+ XPUSHs(sv_2mortal(newSViv(j)));
+ }
+
+int
+MAXO()
+ CODE:
+ RETVAL = maxo;
+ OUTPUT:
+ RETVAL
=head1 NAME
-Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa - load the C
- socket.h defines and structure manipulators
+Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa - load the C socket.h defines and structure manipulators
=head1 SYNOPSIS
# yet. (The user may have set the $install* Configure variables
# to point to some temporary home, from which the executable gets
# installed by occult means.)
- $pod2man = "../perl -I ../lib ../pod/pod2man";
+ $pod2man = "../perl -I ../lib ../pod/pod2man --section=$manext --official";
&makedir($mandir);
# Make a list of all the .pm and .pod files in the directory. We will
$manpage =~ s#\.p(m|od)$##;
$manpage =~ s#/#::#g;
$manpage = "${mandir}/${manpage}.${manext}";
- # Print $release $patchlevel stuff? or should pod2man do that?
&cmd("$pod2man $mod > $manpage");
+ if (-z $manpage) {
+ print STDERR "unlink $manpage\n";
+ unless ($notify) {
+ unlink($manpage) || warn "cannot unlink $manpage: $!";
+ }
+ }
}
chdir "$builddir" || die "Unable to cd back to $builddir directory!\n$!\n";
}
local($cmd) = @_;
print STDERR " $cmd\n";
unless ($notify) {
- system $cmd;
- warn "Command failed!!!\n" if $?;
+ fork ? wait : exec $cmd;
+ warn "Command failed!!\n" if $?;
}
+ return $? != 0;
}
sub link {
AutoSplit - split a package for autoloading
+=head1 SYNOPSIS
+
+ perl -e 'use AutoSplit; autosplit_modules(@ARGV)' ...
+
=head1 DESCRIPTION
This function will split up your program into files that the AutoLoader
The getcwd() function re-implements the getcwd(3) (or getwd(3)) functions
in Perl.
-The fastgetcwd() function looks the same as getcwd(), but runs faster.
+The fastcwd() function looks the same as getcwd(), but runs faster.
It's also more dangerous because you might conceivably chdir() out of a
directory that you can't chdir() back into.
1;
__END__
+
=head1 NAME
Devel::SelfStubber - generate stubs for a SelfLoading module
=head1 NAME
-Env - Perl module that imports environment variables
+Env - perl module that imports environment variables
+
+=head1 SYNOPSIS
+
+ use Env;
+ use Env qw(PATH HOME TERM);
=head1 DESCRIPTION
package Exporter;
-=head1 Comments
+=head1 NAME
+
+Exporter - provide inport/export controls for Perl modules
+
+=head1 SYNOPSIS
+
+use Module;
+use Module qw(name1 name2 :tag /pattern/ !name);
+
+=head1 DESCRIPTION
If the first entry in an import list begins with !, : or / then the
list is treated as a series of specifications which either add to or
1;
__END__
+
=head1 NAME
ExtUtils::Liblist - determine libraries to use and how to use them
package ExtUtils::MakeMaker;
-# Last edited $Date: 1995/12/05 18:20:28 $ by Andreas Koenig
-# $Id: MakeMaker.pm,v 1.115 1995/12/05 18:20:28 k Exp $
+# Last edited $Date: 1995/12/10 23:38:09 $ by Andreas Koenig
+# $Id: MakeMaker.pm,v 1.116 1995/12/10 23:38:09 k Exp $
-$Version = $VERSION = "5.11";
+$Version = $VERSION = "5.12";
$ExtUtils::MakeMaker::Version_OK = 4.13; # Makefiles older than $Version_OK will die
# (Will be checked from MakeMaker version 4.13 onwards)
# version compatibility between the *.pm file and the
# corresponding *.xs file. The bottomline was, that we need an
# XS_VERSION macro that defaults to VERSION:
- $self->{XS_VERSION} ||= $self->{VERSION};
+ # $self->{XS_VERSION} ||= $self->{VERSION};
# --- Initialize Perl Binary Locations
$self->{MAN1PODS} = {};
} else {
my %manifypods = ();
- foreach $name (@{$self->{EXE_FILES}}) {
- local(*TESTPOD);
- my($ispod)=0;
- if (open(TESTPOD,"<$name")) {
- my $testpodline;
- while ($testpodline = <TESTPOD>) {
- if($testpodline =~ /^=head/) {
- $ispod=1;
- last;
+ if( exists $self->{EXE_FILES} ){
+ foreach $name (@{$self->{EXE_FILES}}) {
+ local(*TESTPOD);
+ my($ispod)=0;
+ if (open(TESTPOD,"<$name")) {
+ my $testpodline;
+ while ($testpodline = <TESTPOD>) {
+ if($testpodline =~ /^=head/) {
+ $ispod=1;
+ last;
+ }
+ }
+ close(TESTPOD);
+ } else {
+ # If it doesn't exist yet, we assume, it has pods in it
+ $ispod = 1;
+ }
+ if( $ispod ) {
+ $manifypods{$name} = $self->catdir('$(INST_MAN1DIR)',basename($name).'.$(MAN1EXT)');
}
}
- close(TESTPOD);
- } else {
- # If it doesn't exist yet, we assume, it has pods in it
- $ispod = 1;
- }
- if( $ispod ) {
- $manifypods{$name} = $self->catdir('$(INST_MAN1DIR)',basename($name).'.$(MAN1EXT)');
- }
}
$self->{MAN1PODS} = \%manifypods;
# Compute EXTRALIBS, BSLOADLIBS and LDLOADLIBS from $self->{LIBS}
# Lets look at $self->{LIBS} carefully: It may be an anon array, a string or
# undefined. In any case we turn it into an anon array:
- $self->{LIBS}=[] unless $self->{LIBS};
+
+ # May check $Config{libs} too, thus not empty.
+ $self->{LIBS}=[''] unless $self->{LIBS};
+
$self->{LIBS}=[$self->{LIBS}] if ref \$self->{LIBS} eq SCALAR;
$self->{LD_RUN_PATH} = "";
my($libs);
$self->{UMASK_NULL} = "umask 0";
}
-sub find_perl{
+sub find_perl {
my($self, $ver, $names, $dirs, $trace) = @_;
unless (ref $self){
ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
next unless defined $dir; # $self->{PERL_SRC} may be undefined
foreach $name (@$names){
my $abs;
- if ($name =~ m|^/|) {
+ if ($self->file_name_is_absolute($name)) {
$abs = $name;
- } elsif ($name =~ m|/|) {
- $abs = $self->catfile(".", $name); # not absolute
+ } elsif ($name =~ m|/|) { # file_name_contains_path
+ $abs = $self->catfile(".", $name);
} else {
$abs = $self->catfile($dir, $name);
}
return;
}
+sub perl_script {
+ my($self,$file) = @_;
+ return 1 if -r $file && ! -d $file;
+ return;
+}
+
# Ilya's suggestion, not yet used
sub file_name_is_absolute {
my($self,$file) = @_;
VERSION_SYM = $self->{VERSION_SYM}
VERSION_MACRO = VERSION
DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\"
-XS_VERSION = $self->{XS_VERSION}
-XS_VERSION_MACRO = XS_VERSION
-XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\"
+# XS_VERSION = $self->{XS_VERSION}
+# XS_VERSION_MACRO = XS_VERSION
+# XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\"
# In which directory should we put this extension during 'make'?
# This is typically ./blib.
} else {
$pod2man_exe = "$Config{bin}/pod2man";
}
- unless ($self->maybe_command($pod2man_exe)) {
+ unless ($self->perl_script($pod2man_exe)) {
# No pod2man but some MAN3PODS to be installed
print <<END;
sub installbin {
my($self) = shift;
return "" unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
+ return "" unless @{$self->{EXE_FILES}};
my(@m, $from, $to, %fromto, @to);
push @m, $self->dir_target(qw[$(INST_EXE)]);
for $from (@{$self->{EXE_FILES}}) {
@ echo Appending installation info to $(INSTALLARCHLIB)/perllocal.pod
@ $(PERL) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB) \\
-e "use ExtUtils::MakeMaker; MY->new({})->writedoc('Module', '$(NAME)', \\
- 'LINKTYPE=$(LINKTYPE)', 'VERSION=$(VERSION)', 'XS_VERSION=$(XS_VERSION)', \\
+ 'LINKTYPE=$(LINKTYPE)', 'VERSION=$(VERSION)', \\
'EXE_FILES=$(EXE_FILES)')" >> $(INSTALLARCHLIB)/perllocal.pod
};
C<-noprototypes>. See the xsubpp documentation for details. MakeMaker
defaults to the empty string.
-=item XS_VERSION
-
-Your version number for the XS part of your extension. This defaults
-to S(VERSION).
-
=back
=head2 Additional lowercase attributes
=head1 DESCRIPTION
Mkmanifest() writes all files in and below the current directory to a
-file named C<MANIFEST> in the current directory. It works similar to
+file named in the global variable $ExtUtils::Manifest::MANIFEST (which
+defaults to C<MANIFEST>) in the current directory. It works similar to
find . -print
C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>,
C<&maniread>, and C<&manicopy> are exportable.
+=head1 GLOBAL VARIABLES
+
+C<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it
+results in both a different C<MANIFEST> and a different
+C<MANIFEST.SKIP> file. This is useful if you want to maintain
+different distributions for different audiences (say a user version
+and a developer version including RCS).
+
+<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value,
+all functions act silently.
+
=head1 DIAGNOSTICS
All diagnostic output is sent to C<STDERR>.
=back
+=head1 SEE ALSO
+
+L<ExtUtils::MakeMaker> which has handy targets for most of the functionality.
+
=head1 AUTHOR
Andreas Koenig F<E<lt>koenig@franz.ww.TU-Berlin.DEE<gt>>
$Verbose = 1;
$Is_VMS = $Config{'osname'} eq 'VMS';
-$VERSION = $VERSION = substr(q$Revision: 1.17 $,10,4);
+$VERSION = $VERSION = substr(q$Revision: 1.18 $,10,4);
$Quiet = 0;
+$MANIFEST = 'MANIFEST';
+
# Really cool fix from Ilya :)
unless (defined $Config{d_link}) {
*ln = \&cp;
my $read = maniread() or $manimiss++;
$read = {} if $manimiss;
local *M;
- rename "MANIFEST", "MANIFEST.bak" unless $manimiss;
- open M, ">MANIFEST" or die "Could not open MANIFEST: $!";
+ rename $MANIFEST, "$MANIFEST.bak" unless $manimiss;
+ open M, ">$MANIFEST" or die "Could not open $MANIFEST: $!";
my $matches = _maniskip();
my $found = manifind();
my($key,$val,$file,%all);
foreach $file (sort keys %all) {
next if &$matches($file);
if ($Verbose){
- warn "Added to MANIFEST: $file\n" unless exists $read->{$file};
+ warn "Added to $MANIFEST: $file\n" unless exists $read->{$file};
}
my $text = $all{$file};
($file,$text) = split(/\s+/,$text,2) if $Is_VMS;
if ($arg & 1){
my $found = manifind();
foreach $file (sort keys %$read){
- warn "Debug: manicheck checking from MANIFEST $file\n" if $Debug;
+ warn "Debug: manicheck checking from $MANIFEST $file\n" if $Debug;
unless ( exists $found->{$file} ) {
warn "No such file: $file\n" unless $Quiet;
push @missfile, $file;
}
warn "Debug: manicheck checking from disk $file\n" if $Debug;
unless ( exists $read->{$file} ) {
- warn "Not in MANIFEST: $file\n" unless $Quiet;
+ warn "Not in $MANIFEST: $file\n" unless $Quiet;
push @missentry, $file;
}
}
sub maniread {
my ($mfile) = @_;
- $mfile = "MANIFEST" unless defined $mfile;
+ $mfile = $MANIFEST unless defined $mfile;
my $read = {};
local *M;
unless (open M, $mfile){
my ($mfile) = @_;
my $matches = sub {0};
my @skip ;
- my $mfile = "MANIFEST.SKIP" unless defined $mfile;
+ my $mfile = "$MANIFEST.SKIP" unless defined $mfile;
local *M;
return $matches unless -f $mfile;
open M, $mfile or return $matches;
sub Mkbootstrap {
-=head1 USEFUL SUBROUTINES
+=head1 NAME
-=head2 Mkbootstrap()
+Mkbootstrap - make a bootstrap file for use by DynaLoader
-Make a bootstrap file for use by this system's DynaLoader. It
-typically gets called from an extension Makefile.
+=head1 SYNOPSIS
+
+C<mkbootstrap>
+
+=head1 DESCRIPTION
+
+Mkbootstrap typically gets called from an extension Makefile.
There is no C<*.bs> file supplied with the extension. Instead a
C<*_BS> file which has code for the special cases, like posix for
This file will get parsed, and produce a maybe empty
C<@DynaLoader::dl_resolve_using> array for the current architecture.
-That will be extended by $BSLOADLIBS, which was computed by Andy's
-extliblist script. If this array still is empty, we do nothing, else
-we write a .bs file with an C<@DynaLoader::dl_resolve_using> array, but
-without any C<if>s, because there is no longer a need to deal with
-special cases.
-
-The C<*_BS> file can put some code into the generated C<*.bs> file by placing
-it in C<$bscode>. This is a handy 'escape' mechanism that may prove
-useful in complex situations.
+That will be extended by $BSLOADLIBS, which was computed by
+ExtUtils::Liblist::ext(). If this array still is empty, we do nothing,
+else we write a .bs file with an C<@DynaLoader::dl_resolve_using>
+array.
+
+The C<*_BS> file can put some code into the generated C<*.bs> file by
+placing it in C<$bscode>. This is a handy 'escape' mechanism that may
+prove useful in complex situations.
If @DynaLoader::dl_resolve_using contains C<-L*> or C<-l*> entries then
Mkbootstrap will automatically add a dl_findfile() call to the
# Note that some additional FileHandle methods are defined in POSIX.pm.
-=head1 NAME
+=head1 NAME
FileHandle - supply object methods for filehandles
See L<perlvar> for complete descriptions of each of the following supported C<FileHandle>
methods:
- print
autoflush
output_field_separator
output_record_separator
format_line_break_characters
format_formfeed
+Furthermore, for doing normal I/O you might need these:
+
+=over
+
+=item $fh->print
+
+See L<perlfunc/print>.
+
+=item $fh->printf
+
+See L<perlfunc/printf>.
+
+=item $fh->getline
+
+This works like <$fh> described in L<perlop/"I/O Operators"> except that it's more readable
+and can be safely called in an array context but still
+returns just one line.
+
+=item $fh->getlines
+
+This works like <$fh> when called in an array context to
+read all the remaining lines in a file, except that it's more readable.
+It will also croak() if accidentally called in a scalar context.
+
+=back
+
+=head2 The cacheout() Library
+
The cacheout() function will make sure that there's a filehandle
open for writing available as the pathname you give it. It automatically
closes and re-opens files if you exceed your system file descriptor maximum.
+=head1 SEE ALSO
+
+L<perlfunc>,
+L<perlop/"I/O Operators">,
+L<POSIX/"FileHandle">
+
=head1 BUGS
F<sys/param.h> lies with its C<NOFILE> define on some systems,
so you may have to set $cacheout::maxopen yourself.
+Some of the methods that set variables (like format_name()) don't
+seem to work.
+
+The POSIX functions that create FileHandle methods should be
+in this module instead.
+
Due to backwards compatibility, all filehandles resemble objects
of class C<FileHandle>, or actually classes derived from that class.
They actually aren't. Which means you can't derive your own
require 5.000;
use English;
+use Carp;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(
- print
autoflush
output_field_separator
output_record_separator
format_top_name
format_line_break_characters
format_formfeed
+
+ print
+ printf
+ getline
+ getlines
+
cacheout
);
print $this @_;
}
+sub printf {
+ local($this) = shift;
+ printf $this @_;
+}
+
+sub getline {
+ local($this) = shift;
+ croak "usage: FileHandle::getline()" if @_;
+ return scalar <$this>;
+}
+
+sub getlines {
+ local($this) = shift;
+ croak "usage: FileHandle::getline()" if @_;
+ croak "can't call FileHandle::getlines in a scalar context" if wantarray;
+ return <$this>;
+}
+
sub autoflush {
local($old) = select($_[0]);
local($prev) = $OUTPUT_AUTOFLUSH;
=head1 SYNOPSIS
use IPC::Open2;
- $pid = open2('rdr', 'wtr', 'some cmd and args');
+ $pid = open2(\*RDR, \*WTR, 'some cmd and args');
# or
- $pid = open2('rdr', 'wtr', 'some', 'cmd', 'and', 'args');
+ $pid = open2(\*RDR, \*WTR, 'some', 'cmd', 'and', 'args');
=head1 DESCRIPTION
The big problem with this approach is that if you don't have control
over source code being run in the the child process, you can't control what it does
-with pipe buffering. Thus you can't just open a pipe to "cat -v" and continually
+with pipe buffering. Thus you can't just open a pipe to C<cat -v> and continually
read and write a line from it.
=head1 SEE ALSO
# force unqualified filehandles into callers' package
local($package) = caller;
- $dad_rdr =~ s/^[^']+$/$package'$&/;
- $dad_wtr =~ s/^[^']+$/$package'$&/;
+ $dad_rdr =~ s/^[^']+$/$package'$&/ unless ref $dad_rdr;
+ $dad_wtr =~ s/^[^']+$/$package'$&/ unless ref $dad_wtr;
local($kid_rdr) = ++$fh;
local($kid_wtr) = ++$fh;
=head1 SYNOPSIS
- $pid = open3('WTRFH', 'RDRFH', 'ERRFH'
+ $pid = open3(\*WTRFH, \*RDRFH, \*ERRFH
'some cmd and args', 'optarg', ...);
=head1 DESCRIPTION
">&", then the child will send output directly to that file handle. In both
cases, there will be a dup(2) instead of a pipe(2) made.
+If you try to read from the child's stdout writer and their stderr
+writer, you'll have problems with blocking, which means you'll
+want to use select(), which means you'll have to use sysread() instead
+of normal stuff.
+
All caveats from open2() continue to apply. See L<open2> for details.
=cut
# force unqualified filehandles into callers' package
my($package) = caller;
- $dad_wtr =~ s/^[^:]+$/$package\:\:$&/;
- $dad_rdr =~ s/^[^:]+$/$package\:\:$&/;
- $dad_err =~ s/^[^:]+$/$package\:\:$&/;
+ $dad_wtr =~ s/^[^:]+$/$package\:\:$&/ unless ref $dad_wtr;
+ $dad_rdr =~ s/^[^:]+$/$package\:\:$&/ unless ref $dad_rdr;
+ $dad_err =~ s/^[^:]+$/$package\:\:$&/ unless ref $dad_err;
my($kid_rdr) = ++$fh;
my($kid_wtr) = ++$fh;
1;
__END__
+
=head1 NAME
SelfLoader - load functions only on demand
-# by David Sundstrom sunds@asictest.sc.ti.com
-# Texas Instruments
-
package Sys::Hostname;
use Carp;
@ISA = qw(Exporter);
@EXPORT = qw(hostname);
-#
-# Try every conceivable way to get hostname.
-#
+=head1 NAME
+
+Sys::Hostname - Try every conceivable way to get hostname
+
+=head1 SYNOPSIS
+
+ use Sys::Hostname;
+ $host = hostname;
+
+=head1 DESCRIPTION
+
+Attempts several methods of getting the system hostname and
+then caches the result. It tries C<syscall(SYS_gethostname)>,
+C<`hostname`>, C<`uname -n`>, and the file F</com/host>.
+If all that fails it C<croak>s.
+
+All nulls, returns, and newlines are removed from the result.
+
+=head1 AUTHOR
+
+David Sundstrom <sunds@asictest.sc.ti.com>
+
+Texas Instruments
+
+=cut
sub hostname {
if ($lo_cons) {
if ($pid = fork) {
unless ($lo_nowait) {
- do {$died = wait;} until $died == $pid || $died < 0;
+ $died = waitpid($pid, 0);
}
}
else {
}
sub connect {
- $pat = 'S n C4 x8';
-
- $af_unix = AF_UNIX();
- $af_inet = AF_INET();
-
- $stream = SOCK_STREAM();
- $datagram = SOCK_DGRAM();
-
- ($name,$aliases,$proto) = getprotobyname('udp');
- $udp = $proto;
-
- ($name,$aliase,$port,$proto) = getservbyname('syslog','udp');
- $syslog = $port;
-
- if ($myname = hostname()) {
- ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($myname);
- croak "Can't lookup $myname" unless $name;
- @bytes = unpack("C4",$addrs[0]);
- }
- else {
- @bytes = (0,0,0,0);
- }
- $this = pack($pat, $af_inet, 0, @bytes);
-
- if ($host =~ /^\d+\./) {
- @bytes = split(/\./,$host);
- }
- else {
- ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($host);
- croak "Can't lookup $host" unless $name;
- @bytes = unpack("C4",$addrs[0]);
- }
- $that = pack($pat,$af_inet,$syslog,@bytes);
-
- socket(SYSLOG,$af_inet,$datagram,$udp) || croak "socket: $!";
- bind(SYSLOG,$this) || croak "bind: $!";
- connect(SYSLOG,$that) || croak "connect: $!";
-
+ my $udp = getprotobyname('udp');
+ my $syslog = getservbyname('syslog','udp');
+ my $this = sockaddr_in($syslog, INADDR_ANY);
+ my $that = sockaddr_in($syslog, inet_aton($host) || croak "Can't lookup $host");
+ socket(SYSLOG,AF_INET,SOCK_DGRAM,$udp) || croak "socket: $!";
+ connect(SYSLOG,$that) || croak "connect: $!";
local($old) = select(SYSLOG); $| = 1; select($old);
$connected = 1;
}
-# Term::Cap.pm -- Termcap interface routines
package Term::Cap;
+use Carp;
-# Converted to package on 25 Feb 1994 <sanders@bsdi.com>
-#
-# Usage:
-# require 'ioctl.pl';
-# ioctl(TTY,$TIOCGETP,$sgtty);
-# ($ispeed,$ospeed) = unpack('cc',$sgtty);
-#
-# require Term::Cap;
-#
-# $term = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
-# sets $term->{'_cm'}, etc.
-# $this->Trequire(qw/ce ku kd/);
-# die unless entries are defined for the terminal
-# $term->Tgoto('cm', $col, $row, $FH);
-# $term->Tputs('dl', $cnt = 1, $FH);
-# $this->Tpad($string, $cnt = 1, $FH);
-# processes a termcap string and adds padding if needed
-# if $FH is undefined these just return the string
-#
-# CHANGES:
-# Converted to package
-# Allows :tc=...: in $ENV{'TERMCAP'} (flows to default termcap file)
-# Now die's properly if it can't open $TERMCAP or if the eval $loop fails
-# Tputs() results are cached (use Tgoto or Tpad to avoid)
-# Tgoto() will do output if $FH is passed (like Tputs without caching)
-# Supports POSIX termios speeds and old style speeds
-# Searches termcaps properly (TERMPATH, etc)
-# The output routines are optimized for cached Tputs().
-# $this->{_xx} is the raw termcap data and $this->{xx} is a
-# cached and padded string for count == 1.
-#
+# Last updated: Thu Dec 14 20:02:42 CST 1995 by sanders@bsdi.com
-# internal routines
-sub getenv { defined $ENV{$_[0]} ? $ENV{$_[0]} : ''; }
-sub termcap_path {
- local @termcap_path = ('/etc/termcap', '/usr/share/misc/termcap');
- local $v;
- if ($v = getenv(TERMPATH)) {
- # user specified path
- @termcap_path = split(':', $v);
- } else {
- # default path
- @termcap_path = ('/etc/termcap', '/usr/share/misc/termcap');
- $v = getenv(HOME);
- unshift(@termcap_path, $v . '/.termcap') if $v;
+# TODO:
+# support Berkeley DB termcaps
+# should probably be a .xs module
+# force $FH into callers package?
+# keep $FH in object at Tgetent time?
+
+=head1 NAME
+
+Term::Cap - Perl termcap interface
+
+=head1 SYNOPSIS
+
+ require Term::Cap;
+ $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
+ $terminal->Trequire(qw/ce ku kd/);
+ $terminal->Tgoto('cm', $col, $row, $FH);
+ $terminal->Tputs('dl', $count, $FH);
+ $terminal->Tpad($string, $count, $FH);
+
+=head1 DESCRIPTION
+
+These are low-level functions to extract and use capabilities from
+a terminal capability (termcap) database.
+
+The B<Tgetent> function extracts the entry of the specified terminal
+type I<TERM> (defaults to the environment variable I<TERM>) from the
+database.
+
+It will look in the environment for a I<TERMCAP> variable. If
+found, and the value does not begin with a slash, and the terminal
+type name is the same as the environment string I<TERM>, the
+I<TERMCAP> string is used instead of reading a termcap file. If
+it does begin with a slash, the string is used as a path name of
+the termcap file to search. If I<TERMCAP> does not begin with a
+slash and name is different from I<TERM>, B<Tgetent> searches the
+files F<$HOME/.termcap>, F</etc/termcap>, and F</usr/share/misc/termcap>,
+in that order, unless the environment variable I<TERMPATH> exists,
+in which case it specifies a list of file pathnames (separated by
+spaces or colons) to be searched B<instead>. Whenever multiple
+files are searched and a tc field occurs in the requested entry,
+the entry it names must be found in the same file or one of the
+succeeding files. If there is a C<:tc=...:> in the I<TERMCAP>
+environment variable string it will continue the search in the
+files as above.
+
+I<OSPEED> is the terminal output bit rate (often mistakenly called
+the baud rate). I<OSPEED> can be specified as either a POSIX
+termios/SYSV termio speeds (where 9600 equals 9600) or an old
+BSD-style speeds (where 13 equals 9600).
+
+B<Tgetent> returns a blessed object reference which the user can
+then use to send the control strings to the terminal using B<Tputs>
+and B<Tgoto>. It calls C<croak> on failure.
+
+B<Tgoto> decodes a cursor addressing string with the given parameters.
+
+The output strings for B<Tputs> are cached for counts of 1 for performance.
+B<Tgoto> and B<Tpad> do not cache. C<$self-E<gt>{_xx}> is the raw termcap
+data and C<$self-E<gt>{xx}> is the cached version.
+
+ print $terminal->Tpad($self->{_xx}, 1);
+
+B<Tgoto>, B<Tputs>, and B<Tpad> return the string and will also
+output the string to $FH if specified.
+
+The extracted termcap entry is available in the object
+as C<$self-E<gt>{TERMCAP}>.
+
+=head1 EXAMPLES
+
+ # Get terminal output speed
+ require POSIX;
+ my $termios = new POSIX::Termios;
+ $termios->getattr;
+ my $ospeed = $termios->getospeed;
+
+ # Old-style ioctl code to get ospeed:
+ # require 'ioctl.pl';
+ # ioctl(TTY,$TIOCGETP,$sgtty);
+ # ($ispeed,$ospeed) = unpack('cc',$sgtty);
+
+ # allocate and initialize a terminal structure
+ $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
+
+ # require certain capabilities to be available
+ $terminal->Trequire(qw/ce ku kd/);
+
+ # Output Routines, if $FH is undefined these just return the string
+
+ # Tgoto does the % expansion stuff with the given args
+ $terminal->Tgoto('cm', $col, $row, $FH);
+
+ # Tputs doesn't do any % expansion.
+ $terminal->Tputs('dl', $count = 1, $FH);
+
+=cut
+
+# Returns a list of termcap files to check.
+sub termcap_path { ## private
+ my @termcap_path;
+ # $TERMCAP, if it's a filespec
+ push(@termcap_path, $ENV{TERMCAP}) if $ENV{TERMCAP} =~ /^\//;
+ if ($ENV{TERMPATH}) {
+ # Add the users $TERMPATH
+ push(@termcap_path, split(/(:|\s+)/, $ENV{TERMPATH}))
+ }
+ else {
+ # Defaults
+ push(@termcap_path,
+ $ENV{'HOME'} . '/.termcap',
+ '/etc/termcap',
+ '/usr/share/misc/termcap',
+ );
}
- # we always search TERMCAP first
- $v = getenv(TERMCAP);
- unshift(@termcap_path, $v) if $v =~ /^\//;
+ # return the list of those termcaps that exist
grep(-f, @termcap_path);
}
-sub Tgetent {
- local($type) = shift;
- local($this) = @_;
- local($TERM,$TERMCAP,$term,$entry,$cap,$loop,$field,$entry,$_);
-
- warn "Tgetent: no ospeed set\n" unless $this->{OSPEED} > 0;
- $this->{DECR} = 10000 / $this->{OSPEED} if $this->{OSPEED} > 50;
- $term = $TERM = $this->{TERM} =
- $this->{TERM} || getenv(TERM) || die "Tgetent: TERM not set\n";
-
- $TERMCAP = getenv(TERMCAP);
- $TERMCAP = '' if $TERMCAP =~ m:^/: || $TERMCAP !~ /(^|\|)$TERM[:\|]/;
- local @termcap_path = &termcap_path;
- die "Tgetent: Can't find a valid termcap file\n"
- unless @termcap_path || $TERMCAP;
-
- # handle environment TERMCAP, setup for continuation if needed
- $entry = $TERMCAP;
- $entry =~ s/:tc=([^:]+):/:/ && ($TERM = $1);
- if ($TERMCAP eq '' || $1) { # the search goes on
- local $first = $TERMCAP eq '' ? 1 : 0; # make it pretty
- local $max = 32; # max :tc=...:'s
- local $state = 1; # 0 == finished
- # 1 == next file
- # 2 == search again
- do {
- if ($state == 1) {
- $TERMCAP = shift @termcap_path
- || die "Tgetent: failed lookup on $TERM\n";
- } else {
- $max-- || die "Tgetent: termcap loop at $TERM\n";
- $state = 1; # back to default state
+sub Tgetent { ## public -- static method
+ my $class = shift;
+ my $self = bless shift, $class;
+ my($term,$cap,$search,$field,$max,$tmp_term,$TERMCAP);
+ local($termpat,$state,$first,$entry); # used inside eval
+ local $_;
+
+ # Compute PADDING factor from OSPEED (to be used by Tpad)
+ if (! $self->{OSPEED}) {
+ carp "OSPEED was not set, defaulting to 9600";
+ $self->{OSPEED} = 9600;
+ }
+ if ($self->{OSPEED} < 16) {
+ # delays for old style speeds
+ my @pad = (0,200,133.3,90.9,74.3,66.7,50,33.3,16.7,8.3,5.5,4.1,2,1,.5,.2);
+ $self->{PADDING} = $pad[$self->{OSPEED}];
+ }
+ else {
+ $self->{PADDING} = 10000 / $self->{OSPEED};
+ }
+
+ $self->{TERM} = ($self->{TERM} || $ENV{TERM} || croak "TERM not set");
+ $term = $self->{TERM}; # $term is the term type we are looking for
+
+ # $tmp_term is always the next term (possibly :tc=...:) we are looking for
+ $tmp_term = $self->{TERM};
+ # protect any pattern metacharacters in $tmp_term
+ $termpat = $tmp_term; $termpat =~ s/(\W)/\\$1/g;
+
+ my $foo = $ENV{TERMCAP};
+
+ # $entry is the extracted termcap entry
+ if (($foo !~ m:^/:) && ($foo =~ m/(^|\|)${termpat}[:|]/)) {
+ $entry = $foo;
+ }
+
+ my @termcap_path = termcap_path;
+ croak "Can't find a valid termcap file" unless @termcap_path || $entry;
+
+ $state = 1; # 0 == finished
+ # 1 == next file
+ # 2 == search again
+
+ $first = 0; # first entry (keeps term name)
+
+ $max = 32; # max :tc=...:'s
+
+ if ($entry) {
+ # ok, we're starting with $TERMCAP
+ $first++; # we're the first entry
+ # do we need to continue?
+ if ($entry =~ s/:tc=([^:]+):/:/) {
+ $tmp_term = $1;
+ # protect any pattern metacharacters in $tmp_term
+ $termpat = $tmp_term; $termpat =~ s/(\W)/\\$1/g;
+ }
+ else {
+ $state = 0; # we're already finished
+ }
+ }
+
+ # This is eval'ed inside the while loop for each file
+ $search = q{
+ while ($_ = <TERMCAP>) {
+ next if /^\\t/ || /^#/;
+ if ($_ =~ m/(^|\\|)${termpat}[:|]/o) {
+ chomp;
+ s/^[^:]*:// if $first++;
+ $state = 0;
+ while ($_ =~ s/\\\\$//) { $_ .= <TERMCAP>; chomp; }
+ last;
}
+ }
+ $entry .= $_;
+ };
- open(TERMCAP,"< $TERMCAP\0") || die "Tgetent: $TERMCAP: $!\n";
- # print STDERR "Trying... $TERMCAP\n";
- $loop = "
- while (<TERMCAP>) {
- next if /^\t/;
- next if /^#/;
- if (/(^|\\|)${TERM}[:\\|]/) {
- chop;
- s/^[^:]*:// unless \$first++;
- \$state = 0;
- while (chop eq '\\\\') {
- \$_ .= <TERMCAP>;
- chop;
- }
- \$_ .= ':';
- last;
- }
- }
- \$entry .= \$_;
- ";
- eval $loop;
- die $@ if $@;
- #print STDERR "$TERM: $_\n--------\n"; # DEBUG
- close TERMCAP;
- # If :tc=...: found then search this file again
- $entry =~ s/:tc=([^:]+):/:/ && ($TERM = $1, $state = 2);
- } while $state != 0;
+ while ($state != 0) {
+ if ($state == 1) {
+ # get the next TERMCAP
+ $TERMCAP = shift @termcap_path
+ || croak "failed termcap lookup on $tmp_term";
+ }
+ else {
+ # do the same file again
+ # prevent endless recursion
+ $max-- || croak "failed termcap loop at $tmp_term";
+ $state = 1; # ok, maybe do a new file next time
+ }
+
+ open(TERMCAP,"< $TERMCAP\0") || croak "open $TERMCAP: $!";
+ eval $search;
+ die $@ if $@;
+ close TERMCAP;
+
+ # If :tc=...: found then search this file again
+ $entry =~ s/:tc=([^:]+):/:/ && ($tmp_term = $1, $state = 2);
+ # protect any pattern metacharacters in $tmp_term
+ $termpat = $tmp_term; $termpat =~ s/(\W)/\\$1/g;
}
- die "Tgetent: Can't find $term\n" unless $entry ne '';
- $entry =~ s/:\s+:/:/g;
- $this->{TERMCAP} = $entry;
- #print STDERR $entry, "\n"; # DEBUG
+
+ croak "Can't find $term" if $entry eq '';
+ $entry =~ s/:+\s*:+/:/g; # cleanup $entry
+ $entry =~ s/:+/:/g; # cleanup $entry
+ $self->{TERMCAP} = $entry; # save it
+ # print STDERR "DEBUG: $entry = ", $entry, "\n";
# Precompile $entry into the object
+ $entry =~ s/^[^:]*://;
foreach $field (split(/:[\s:\\]*/,$entry)) {
- if ($field =~ /^\w\w$/) {
- $this->{'_' . $field} = 1 unless defined $this->{'_' . $1};
+ if ($field =~ /^(\w\w)$/) {
+ $self->{'_' . $field} = 1 unless defined $self->{'_' . $1};
+ # print STDERR "DEBUG: flag $1\n";
}
elsif ($field =~ /^(\w\w)\@/) {
- $this->{'_' . $1} = "";
+ $self->{'_' . $1} = "";
+ # print STDERR "DEBUG: unset $1\n";
}
elsif ($field =~ /^(\w\w)#(.*)/) {
- $this->{'_' . $1} = $2 unless defined $this->{'_' . $1};
+ $self->{'_' . $1} = $2 unless defined $self->{'_' . $1};
+ # print STDERR "DEBUG: numeric $1 = $2\n";
}
elsif ($field =~ /^(\w\w)=(.*)/) {
- next if defined $this->{'_' . ($cap = $1)};
+ # print STDERR "DEBUG: string $1 = $2\n";
+ next if defined $self->{'_' . ($cap = $1)};
$_ = $2;
s/\\E/\033/g;
s/\\(\d\d\d)/pack('c',oct($1) & 0177)/eg;
s/\^(.)/pack('c',ord($1) & 31)/eg;
s/\\(.)/$1/g;
s/\377/^/g;
- $this->{'_' . $cap} = $_;
+ $self->{'_' . $cap} = $_;
}
- # else { warn "Tgetent: junk in $term: $field\n"; }
+ # else { carp "junk in $term ignored: $field"; }
}
- $this->{'_pc'} = "\0" unless defined $this->{'_pc'};
- $this->{'_bc'} = "\b" unless defined $this->{'_bc'};
- $this;
+ $self->{'_pc'} = "\0" unless defined $self->{'_pc'};
+ $self->{'_bc'} = "\b" unless defined $self->{'_bc'};
+ $self;
}
-# delays for old style speeds
-@Tpad = (0,200,133.3,90.9,74.3,66.7,50,33.3,16.7,8.3,5.5,4.1,2,1,.5,.2);
-
-# $term->Tpad($string, $cnt, $FH);
-sub Tpad {
- local($this, $string, $cnt, $FH) = @_;
- local($decr, $ms);
+# $terminal->Tpad($string, $cnt, $FH);
+sub Tpad { ## public
+ my $self = shift;
+ my($string, $cnt, $FH) = @_;
+ my($decr, $ms);
if ($string =~ /(^[\d.]+)(\*?)(.*)$/) {
$ms = $1;
$ms *= $cnt if $2;
$string = $3;
- $decr = $this->{OSPEED} < 50 ? $Tpad[$this->{OSPEED}] : $this->{DECR};
+ $decr = $self->{PADDING};
if ($decr > .1) {
$ms += $decr / 2;
- $string .= $this->{'_pc'} x ($ms / $decr);
+ $string .= $self->{'_pc'} x ($ms / $decr);
}
}
print $FH $string if $FH;
$string;
}
-# $term->Tputs($cap, $cnt, $FH);
-sub Tputs {
- local($this, $cap, $cnt, $FH) = @_;
- local $string;
+# $terminal->Tputs($cap, $cnt, $FH);
+sub Tputs { ## public
+ my $self = shift;
+ my($cap, $cnt, $FH) = @_;
+ my $string;
if ($cnt > 1) {
- $string = Tpad($this, $this->{'_' . $cap}, $cnt);
+ $string = Tpad($self, $self->{'_' . $cap}, $cnt);
} else {
- $string = defined $this->{$cap} ? $this->{$cap} :
- ($this->{$cap} = Tpad($this, $this->{'_' . $cap}, 1));
+ # cache result because Tpad can be slow
+ $string = defined $self->{$cap} ? $self->{$cap} :
+ ($self->{$cap} = Tpad($self, $self->{'_' . $cap}, 1));
}
print $FH $string if $FH;
$string;
# %n exclusive-or all parameters with 0140 (Datamedia 2500)
# %D Reverse coding (value - 2*(value%16)), no output (Delta Data)
#
-# $term->Tgoto($cap, $col, $row, $FH);
-sub Tgoto {
- local($this, $cap, $code, $tmp, $FH) = @_;
- local $string = $this->{'_' . $cap};
- local $result = '';
- local $after = '';
- local $online = 0;
- local @tmp = ($tmp,$code);
- local $cnt = $code;
+# $terminal->Tgoto($cap, $col, $row, $FH);
+sub Tgoto { ## public
+ my $self = shift;
+ my($cap, $code, $tmp, $FH) = @_;
+ my $string = $self->{'_' . $cap};
+ my $result = '';
+ my $after = '';
+ my $online = 0;
+ my @tmp = ($tmp,$code);
+ my $cnt = $code;
while ($string =~ /^([^%]*)%(.)(.*)/) {
$result .= $1;
$tmp = shift(@tmp);
if ($tmp == 0 || $tmp == 4 || $tmp == 10) {
if ($online) {
- ++$tmp, $after .= $this->{'_up'} if $this->{'_up'};
+ ++$tmp, $after .= $self->{'_up'} if $self->{'_up'};
}
else {
- ++$tmp, $after .= $this->{'_bc'};
+ ++$tmp, $after .= $self->{'_bc'};
}
}
$result .= sprintf("%c",$tmp);
return "OOPS";
}
}
- $string = Tpad($this, $result . $string . $after, $cnt);
+ $string = Tpad($self, $result . $string . $after, $cnt);
print $FH $string if $FH;
$string;
}
-# $this->Trequire($cap1, $cap2, ...);
-sub Trequire {
- local $this = shift;
- local $_;
- foreach (@_) {
- die "Trequire: Terminal does not support: $_\n"
- unless defined $this->{'_' . $_} && $this->{'_' . $_};
+# $terminal->Trequire(qw/ce ku kd/);
+sub Trequire { ## public
+ my $self = shift;
+ my($cap,@undefined);
+ foreach $cap (@_) {
+ push(@undefined, $cap)
+ unless defined $self->{'_' . $cap} && $self->{'_' . $cap};
}
+ croak "Terminal does not support: (@undefined)" if @undefined;
}
1;
+
@ISA = qw(Exporter);
@EXPORT = qw(Complete);
-#
# @(#)complete.pl,v1.1 (me@anywhere.EBay.Sun.COM) 09/23/91
-#
-# Author: Wayne Thompson
-#
-# Description:
-# This routine provides word completion.
-# (TAB) attempts word completion.
-# (^D) prints completion list.
-# (These may be changed by setting $Complete::complete, etc.)
-#
-# Diagnostics:
-# Bell when word completion fails.
-#
-# Dependencies:
-# The tty driver is put into raw mode.
-#
-# Bugs:
-#
-# Usage:
-# $input = complete('prompt_string', \@completion_list);
-# or
-# $input = complete('prompt_string', @completion_list);
-#
+
+=head1 NAME
+
+Term::Complete - Perl word completion module
+
+=head1 SYNOPSIS
+
+ $input = complete('prompt_string', \@completion_list);
+ $input = complete('prompt_string', @completion_list);
+
+=head1 DESCRIPTION
+
+This routine provides word completion on the list of words in
+the array (or array ref).
+
+The tty driver is put into raw mode using the system command
+C<stty raw -echo> and restored using C<stty -raw echo>.
+
+The following command characters are defined:
+
+=over 4
+
+=item <tab>
+Attempts word completion.
+Cannot be changed.
+
+=item ^D
+
+Prints completion list.
+Defined by I<$Term::Complete::complete>.
+
+=item ^U
+
+Erases the current input.
+Defined by I<$Term::Complete::kill>.
+
+=item <del>, <bs>
+
+Erases one character.
+Defined by I<$Term::Complete::erase1> and I<$Term::Complete::erase2>.
+
+=back
+
+=head1 DIAGNOSTICS
+
+Bell sounds when word completion fails.
+
+=head1 BUGS
+
+The completion charater <tab> cannot be changed.
+
+=head1 AUTHOR
+
+Wayne Thompson
+
+=cut
CONFIG: {
$complete = "\004";
$path_s = $Is_OS2 ? ';' : ':' ;
@ISA=(Exporter);
-@EXPORT= qw(&runtests &test_lib);
+@EXPORT= qw(&runtests);
@EXPORT_OK= qw($verbose $switches);
$verbose = 0;
}
1;
+__END__
+
+=head1 NAME
+
+Test::Harness - run perl standard test scripts with statistics
+
+=head1 SYNOPSIS
+
+use Test::Harness;
+
+runtests(@tests);
+
+=head1 DESCRIPTION
+
+Perl test scripts print to standard output C<"ok N"> for each single
+test, where C<N> is an increasing sequence of integers. The first line
+output by a standard test scxript is C<"1..M"> with C<M> being the
+number of tests that should be run within the test
+script. Test::Harness::runscripts(@tests) runs all the testscripts
+named as arguments and checks standard output for the expected
+C<"ok N"> strings.
+
+After all tests have been performed, runscripts() prints some
+performance statistics that are computed by the Benchmark module.
+
+=head1 EXPORT
+
+C<&runscripts> is exported by Test::Harness per default.
+
+=head1 DIAGNOSTICS
+
+=over 4
+
+=item C<All tests successful.\nFiles=%d, Tests=%d, %s>
+
+If all tests are successful some statistics about the performance are
+printed.
+
+=item C<Failed 1 test, $pct% okay.>
+
+=item C<Failed %d/%d tests, %.2f%% okay.>
+
+If not all tests were successful, the script dies with one of the
+above messages.
+
+=back
+
+=head1 SEE ALSO
+
+See L<Benchmerk> for the underlying timing routines.
+
+=head1 BUGS
+
+Test::Harness uses $^X to determine the perl binary to run the tests
+with. Test scripts running via the shebang (C<#!>) line may not be portable
+because $^X is not consistent for shebang scripts across
+platforms. This is no problem when Test::Harness is run with an
+absolute path to the perl binary.
+
+=cut
$soundex_nocode = undef;
-# soundex
-#
-# usage:
-#
-# @codes = &soundex (@wordList);
-# $code = &soundex ($word);
-#
-# This strenuously avoids 0
-
sub soundex
{
local (@s, $f, $fc, $_) = @_;
+ push @s, '' unless @s; # handle no args as a single empty string
+
foreach (@s)
{
tr/a-z/A-Z/;
1;
+__END__
+
+=head1 NAME
+
+Text::Soundex - Implementation of the Soundex Algorithm as Described by Knuth
+
+=head1 SYNOPSIS
+
+ use Text::Soundex;
+
+ $code = soundex $string; # get soundex code for a string
+ @codes = soundex @list; # get list of codes for list of strings
+
+ # set value to be returned for strings without soundex code
+
+ $soundex_nocode = 'Z000';
+
+=head1 DESCRIPTION
+
+This module implements the soundex algorithm as described by Donald Knuth
+in Volume 3 of B<The Art of Computer Programming>. The algorithm is
+intended to hash words (in particular surnames) into a small space using a
+simple model which approximates the sound of the word when spoken by an English
+speaker. Each word is reduced to a four character string, the first
+character being an upper case letter and the remaining three being digits.
+
+If there is no soundex code representation for a string then the value of
+C<$soundex_nocode> is returned. This is initially set to C<undef>, but
+many people seem to prefer an I<unlikely> value like C<Z000>
+(how unlikely this is depends on the data set being dealt with.) Any value
+can be assigned to C<$soundex_nocode>.
+
+In scalar context C<soundex> returns the soundex code of its first
+argument, and in array context a list is returned in which each element is the
+soundex code for the corresponding argument passed to C<soundex> e.g.
+
+ @codes = soundex qw(Mike Stok);
+
+leaves C<@codes> containing C<('M200', 'S320')>.
+
+=head1 EXAMPLES
+
+Knuth's examples of various names and the soundex codes they map to
+are listed below:
+
+ Euler, Ellery -> E460
+ Gauss, Ghosh -> G200
+ Hilbert, Heilbronn -> H416
+ Knuth, Kant -> K530
+ Lloyd, Ladd -> L300
+ Lukasiewicz, Lissajous -> L222
+
+so:
+
+ $code = soundex 'Knuth'; # $code contains 'K530'
+ @list = soundex qw(Lloyd Gauss); # @list contains 'L300', 'G200'
+
+=head1 LIMITATIONS
+
+As the soundex algorithm was originally used a B<long> time ago in the US
+it considers only the English alphabet and pronunciation.
+
+As it is mapping a large space (arbitrary length strings) onto a small
+space (single letter plus 3 digits) no inference can be made about the
+similarity of two strings which end up with the same soundex code. For
+example, both C<Hilbert> and C<Heilbronn> end up with a soundex code
+of C<H416>.
+
+=head1 AUTHOR
+
+This code was implemented by Mike Stok (C<stok@cybercom.net>) from the
+description given by Knuth. Ian Phillips (C<ian@pipex.net>) and Rich Pinder
+(C<rpinder@hsc.usc.edu>) supplied ideas and spotted mistakes.
# Version: 9/21/95
#
+=head1 NAME
+
+Text::Tabs -- expand and unexpand tabs
+
+=head1 SYNOPSIS
+
+ use Text::Tabs;
+
+ #$tabstop = 8; # Defaults
+ print expand("Hello\tworld");
+ print unexpand("Hello, world");
+ $tabstop = 4;
+ print join("\n",expand(split(/\n/,
+ "Hello\tworld,\nit's a nice day.\n"
+ )));
+
+=head1 DESCRIPTION
+
+This module expands and unexpands tabs into spaces, as per the unix expand
+and unexpand programs. Either function should be passed an array of strings
+(newlines may I<not> be included, and should be used to split an incoming
+string into separate elements.) which will be processed and returned.
+
+=head1 AUTHOR
+
+David Muir Sharnoff <muir@idiom.com>
+
+=cut
+
package Text::Tabs;
require Exporter;
# Version: 9/21/95
#
+=head1 NAME
+
+Text::Wrap -- wrap text into a paragraph
+
+=head1 SYNOPSIS
+
+ use Text::Wrap;
+
+ $Text::Wrap::columns = 20; # Default
+ print wrap("\t","",Hello, world, it's a nice day, isn't it?");
+
+=head1 DESCRIPTION
+
+This module is a simple paragraph formatter that wraps text into a paragraph
+and indents each line. The single exported function, wrap(), takes three
+arguments. The first is included before the first output line, and the
+second argument is included before each subsequest output line. The third
+argument is the text to be wrapped.
+
+=head1 AUTHOR
+
+David Muir Sharnoff <muir@idiom.com>
+
+=cut
+
require Exporter;
@ISA = (Exporter);
package TieHash;
+
+=head1 NAME
+
+TieHash, TieHash::Std - base class definitions for tied hashes
+
+=head1 SYNOPSIS
+
+ package NewHash;
+ require TieHash;
+
+ @ISA = (TieHash);
+
+ sub DELETE { ... } # Provides needed method
+ sub CLEAR { ... } # Overrides inherited method
+
+
+ package NewStdHash;
+ require TieHash;
+
+ @ISA = (TieHash::Std);
+
+ # All methods provided by default, define only those needing overrides
+ sub DELETE { ... }
+
+
+ package main;
+
+ tie %new_hash, NewHash;
+ tie %new_std_hash, NewStdHash;
+
+=head1 DESCRIPTION
+
+This module provides some skeletal methods for hash-tying classes. See
+L<perlfunc/tie> for a list of the functions required in order to tie a hash
+to a package. The basic B<TieHash> package provides a C<new> method, as well
+as methods C<TIEHASH>, C<EXISTS> and C<CLEAR>. The B<TieHash::Std> package
+provides most methods required for hashes in L<perlfunc/tie>. It inherits from
+B<TieHash>, and causes tied hashes to behave exactly like standard hashes,
+allowing for selective overloading of methods. The B<new> method is provided
+as grandfathering in the case a class forgets to include a B<TIEHASH> method.
+
+For developers wishing to write their own tied hashes, the required methods
+are:
+
+=item TIEHASH classname, LIST
+
+The method invoked by the command C<tie %hash, class>. Associates a new
+hash instance with the specified class. C<LIST> would represent additional
+arguments (along the lines of L<AnyDBM_File> and compatriots) needed to
+complete the association.
+
+=item STORE this, key, value
+
+Store datum I<value> into I<key> for the tied hash I<this>.
+
+=item FETCH this, key
+
+Retrieve the datum in I<key> for the tied hash I<this>.
+
+=item FIRSTKEY this
+
+Return the (key, value) pair for the first key in the hash.
+
+=item NEXTKEY this, lastkey
+
+Return the next (key, value) pair for the hash.
+
+=item EXISTS this, key
+
+Verify that I<key> exists with the tied hash I<this>.
+
+=item DELETE this, key
+
+Delete the key I<key> from the tied hash I<this>.
+
+=item CLEAR this
+
+Clear all values from the tied hash I<this>.
+
+=back
+
+=head1 CAVEATS
+
+The L<perlfunc/tie> documentation includes a method called C<DESTROY> as
+a necessary method for tied hashes. Neither B<TieHash> nor B<TieHash::Std>
+define a default for this method.
+
+The C<CLEAR> method provided by these two packages is not listed in the
+L<perlfunc/tie> section.
+
+=head1 MORE INFORMATION
+
+The packages relating to various DBM-related implemetations (F<DB_File>,
+F<NDBM_File>, etc.) show examples of general tied hashes, as does the
+L<Config> module. While these do not utilize B<TieHash>, they serve as
+good working examples.
+
+=cut
+
use Carp;
sub new {
@ISA = qw(Exporter);
@EXPORT = qw(timegm timelocal);
-# timelocal.pl
-#
-# Usage:
-# $time = timelocal($sec,$min,$hours,$mday,$mon,$year);
-# $time = timegm($sec,$min,$hours,$mday,$mon,$year);
-
-# These routines are quite efficient and yet are always guaranteed to agree
-# with localtime() and gmtime(). We manage this by caching the start times
-# of any months we've seen before. If we know the start time of the month,
-# we can always calculate any time within the month. The start times
-# themselves are guessed by successive approximation starting at the
-# current time, since most dates seen in practice are close to the
-# current date. Unlike algorithms that do a binary search (calling gmtime
-# once for each bit of the time value, resulting in 32 calls), this algorithm
-# calls it at most 6 times, and usually only once or twice. If you hit
-# the month cache, of course, it doesn't call it at all.
-
-# timelocal is implemented using the same cache. We just assume that we're
-# translating a GMT time, and then fudge it when we're done for the timezone
-# and daylight savings arguments. The timezone is determined by examining
-# the result of localtime(0) when the package is initialized. The daylight
-# savings offset is currently assumed to be one hour.
-
-# Both routines return -1 if the integer limit is hit. I.e. for dates
-# after the 1st of January, 2038 on most machines.
+=head1 NAME
+
+Time::Local - efficiently compute tome from local and GMT time
+
+=head1 SYNOPSIS
+
+ $time = timelocal($sec,$min,$hours,$mday,$mon,$year);
+ $time = timegm($sec,$min,$hours,$mday,$mon,$year);
+
+=head1 DESCRIPTION
+
+These routines are quite efficient and yet are always guaranteed to agree
+with localtime() and gmtime(). We manage this by caching the start times
+of any months we've seen before. If we know the start time of the month,
+we can always calculate any time within the month. The start times
+themselves are guessed by successive approximation starting at the
+current time, since most dates seen in practice are close to the
+current date. Unlike algorithms that do a binary search (calling gmtime
+once for each bit of the time value, resulting in 32 calls), this algorithm
+calls it at most 6 times, and usually only once or twice. If you hit
+the month cache, of course, it doesn't call it at all.
+
+timelocal is implemented using the same cache. We just assume that we're
+translating a GMT time, and then fudge it when we're done for the timezone
+and daylight savings arguments. The timezone is determined by examining
+the result of localtime(0) when the package is initialized. The daylight
+savings offset is currently assumed to be one hour.
+
+Both routines return -1 if the integer limit is hit. I.e. for dates
+after the 1st of January, 2038 on most machines.
+
+=cut
@epoch = localtime(0);
$tzmin = $epoch[2] * 60 + $epoch[1]; # minutes east of GMT
=head1 NAME
-less - Perl pragma to request less of something from the compiler
+less - perl pragma to request less of something from the compiler
+
+=head1 SYNOPSIS
+
+ use less; # unimplemented
=head1 DESCRIPTION
=head1 NAME
-C<overload.pm> - Package for overloading perl operations
+overload - Package for overloading perl operations
=head1 SYNOPSIS
=item C<strict subs>
-This disables the poetry optimization,
-generating a compile-time error if you
-try to use a bareword identifier that's not a subroutine.
+This disables the poetry optimization, generating a compile-time error if
+you try to use a bareword identifier that's not a subroutine, unless it
+appears in curly braces or on the left hand side of the "=>" symbol.
+
use strict 'subs';
$SIG{PIPE} = Plumber; # blows up
- $SIG{"PIPE"} = "Plumber"; # just fine
+ $SIG{PIPE} = "Plumber"; # just fine: bareword in curlies always ok
+ $SIG{PIPE} = \&Plumber; # preferred form
+
+
=back
$host = 'localhost' unless $host; # set $syslog'host to change
+if ($] >= 5) {
+ warn "You should 'use Sys::Socket' instead; continuing" # if $^W
+}
+
require 'syslog.ph';
+ eval 'require Socket' ||
+eval { require "socket.ph" } ||
+ require "sys/socket.ph";
+
$maskpri = &LOG_UPTO(&LOG_DEBUG);
sub main'openlog {
sub connect {
$pat = 'S n C4 x8';
- $af_unix = 1;
- $af_inet = 2;
+ $af_unix = &AF_UNIX;
+ $af_inet = &AF_INET;
- $stream = 1;
- $datagram = 2;
+ $stream = &SOCK_STREAM;
+ $datagram = &SOCK_DGRAM;
($name,$aliases,$proto) = getprotobyname('udp');
$udp = $proto;
- ($name,$aliase,$port,$proto) = getservbyname('syslog','udp');
+ ($name,$aliases,$port,$proto) = getservbyname('syslog','udp');
$syslog = $port;
if (chop($myname = `hostname`)) {
s++;
return s;
case 'v':
- printf("\nThis is perl, version %s beta\n\n",patchlevel);
+ printf("\nThis is perl, version %s beta1g\n\n",patchlevel);
fputs("\nCopyright 1987-1995, Larry Wall\n",stdout);
#ifdef MSDOS
fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
all: $(CONVERTERS) man
-PERL = ../miniperl
+#PERL = ../miniperl
POD = \
perl.pod \
perllol.pod \
perlmod.pod \
perlobj.pod \
+ perltie.pod \
perlop.pod \
- perlovl.pod \
perlpod.pod \
perlre.pod \
perlref.pod \
perlstyle.pod \
perlsub.pod \
perlsyn.pod \
+ perltoc.pod \
perltrap.pod \
perlvar.pod \
perlxs.pod \
- perlxstut.pod
+ perlxstut.pod
MAN = \
perl.man \
perllol.man \
perlmod.man \
perlobj.man \
+ perltie.man \
perlop.man \
- perlovl.man \
perlpod.man \
perlre.man \
perlref.man \
perlstyle.man \
perlsub.man \
perlsyn.man \
+ perltoc.man \
perltrap.man \
perlvar.man \
perlxs.man \
- perlxstut.man
+ perlxstut.man
HTML = \
perl.html \
perllol.html \
perlmod.html \
perlobj.html \
+ perltie.html \
perlop.html \
- perlovl.html \
perlpod.html \
perlre.html \
perlref.html \
perlstyle.html \
perlsub.html \
perlsyn.html \
+ perltoc.html \
perltrap.html \
perlvar.html \
perlxs.html \
- perlxstut.html
+ perlxstut.html
TEX = \
perl.tex \
perllol.tex \
perlmod.tex \
perlobj.tex \
+ perltie.tex \
perlop.tex \
- perlovl.tex \
perlpod.tex \
perlre.tex \
perlref.tex \
perlstyle.tex \
perlsub.tex \
perlsyn.tex \
+ perltoc.tex \
perltrap.tex \
perlvar.tex \
perlxs.tex \
# pod2html normally runs on all the pods at once in order to build up
# cross-references.
-html: pod2html
- $(PERL) pod2html *.pod
+html: pod2html
+ $(PERL) pod2html $(POD)
tex: pod2latex $(TEX)
-.SUFFIXES: .pod .man
+.SUFFIXES: .pm .pod .man
+
+.pm.man: pod2man
+ $(PERL) pod2man $*.pm >$*.man
.pod.man: pod2man
$(PERL) pod2man $*.pod >$*.man
-.SUFFIXES: .pod .html
+.SUFFIXES: .mp .pod .html
+
+.pm.html: pod2html
+ $(PERL) pod2html $*.pod
.pod.html: pod2html
$(PERL) pod2html $*.pod
-.SUFFIXES: .pod .tex
+.SUFFIXES: .pm .pod .tex
.pod.tex: pod2latex
$(PERL) pod2latex $*.pod
+.pm.tex: pod2latex
+ $(PERL) pod2latex $*.pod
+
clean:
rm -f $(MAN) $(HTML) $(TEX)
--- /dev/null
+package PerlDoc::Functions;
+
+#:vi:set ts=20
+
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw(%Kinds %Type %Flavor %Type_Descriptions @Type_Order);
+
+%Type_Description = (
+ 'ARRAY' => 'Functions for real @ARRAYs',
+ 'Binary' => 'Functions for fixed length data or records',
+ 'File' => 'Functions for filehandles, files, or directories',
+ 'Flow' => 'Keywords related to control flow of your perl program',
+ 'HASH' => 'Functions for real %HASHes',
+ 'I/O' => 'Input and output functions',
+ 'LIST' => 'Functions for list data',
+ 'Math' => 'Numeric functions',
+ 'Misc' => 'Miscellaneous functions',
+ 'Modules' => 'Keywords related to perl modules',
+ 'Network' => 'Fetching network info',
+ 'Objects' => 'Keywords related to classes and object-orientedness',
+ 'Process' => 'Functions for processes and process groups',
+ 'Regexp' => 'Regular expressions and pattern matching',
+ 'Socket' => 'Low-level socket functions',
+ 'String' => 'Functions for SCALARs or strings',
+ 'SysV' => 'System V interprocess communication functions',
+ 'Time' => 'Time-related functions',
+ 'User' => 'Fetching user and group info',
+ 'Namespace' => 'Keywords altering or affecting scoping of identifiers',
+);
+
+@Type_Order = qw{
+ String
+ Regexp
+ Math
+ ARRAY
+ LIST
+ HASH
+ I/O
+ Binary
+ File
+ Flow
+ Namespace
+ Misc
+ Process
+ Modules
+ Objects
+ Socket
+ SysV
+ User
+ Network
+ Time
+};
+
+while (<DATA>) {
+ chomp;
+ s/#.*//;
+ next unless $_;
+ ($name, $type, $text) = split " ", $_, 3;
+ $Type{$name} = $type;
+ $Flavor{$name} = $text;
+ for $type ( split /[,\s]+/, $type ) {
+ push @{$Kinds{$type}}, $name;
+ }
+}
+
+unless (caller) {
+ foreach $type ( @Type_Order ) {
+ $list = join(", ", sort @{$Kinds{$type}});
+ $typedesc = $Type_Description{$type} . ":";
+ write;
+ }
+}
+
+format =
+
+^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $typedesc
+~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $typedesc
+ ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ $list
+.
+
+1
+
+__DATA__
+-X File a file test (-r, -x, etc)
+abs Math absolute value function
+accept Socket accept an incoming socket connect
+alarm Process schedule a SIGALRM
+atan2 Math arctangent of Y/X
+bind Socket binds an address to a socket
+binmode I/O prepare binary files on old systems
+bless Objects create an object
+caller Flow,Namespace get context of the current subroutine call
+chdir File change your current working directory
+chmod File changes the permissions on a list of files
+chomp String remove a trailing record separator from a string
+chop String remove the last character from a string
+chown File change the owership on a list of files
+chr String get character this number represents
+chroot File make directory new root for path lookups
+close I/O close file (or pipe or socket) handle
+closedir I/O close directory handle
+connect Socket connect to a remove socket
+continue Flow optional trailing block in a while or foreach
+cos Math cosine function
+crypt String one-way passwd-style encryption
+dbmclose Objects,I/O breaks binding on a tied dbm file
+dbmopen Objects,I/O create binding on a tied dbm file
+defined Misc test whether a value, variable, or function is defined
+delete HASH deletes a value from a hash
+die I/O,Flow raise an exception or bail out
+do Flow,Modules turn a BLOCK into a TERM
+dump Misc,Flow create an immediate core dump
+each HASH retrieve the next key/value pair from a hash
+endgrent User be done using group file
+endhostent User be done using hosts file
+endnetent User be done using networks file
+endprotoent Network be done using protocols file
+endpwent User be done using passwd file
+endservent Network be done using services file
+eof I/O test a filehandle for its end
+eval Flow,Misc catch exceptions or compile code
+exec Process abandon this program to run another
+exists HASH test whether a hash key is present
+exit Flow terminate this program
+exp Math raise I<e> to a power
+fcntl File file control system all
+fileno I/O return file descriptor from filehandle
+flock I/O lock an entire file with an advisory lock
+fork Process create a new process just like this one
+format I/O declare a picture format with use by the write() function
+formline Misc internal function used for formats
+getc I/O get the next character from the filehandle
+getgrent User get next group record
+getgrgid User get group record given group user ID
+getgrnam User get group record given group name
+gethostbyaddr Network get host record given its address
+gethostbyname Network get host record given name
+gethostent Network get next hosts record
+getlogin User return who logged in at this tty
+getnetbyaddr Network get network record given its address
+getnetbyname Network get networks record given name
+getnetent Network get next networks record
+getpeername Socket find the other hend of a socket connection
+getpgrp Process get process group
+getppid Process get parent process ID
+getpriority Process get current nice value
+getprotobyname Network get protocol record given name
+getprotobynumber Network get protocol record numeric protocol
+getprotoent Network get next protocols record
+getpwent User get next passwd record
+getpwnam User get passwd record given user login name
+getpwuid User get passwd record given user ID
+getservbyname Network get services record given its name
+getservbyport Network get services record given numeric port
+getservent Network get next services record
+getsockname Socket retrieve the sockaddr for a given socket
+getsockopt Socket get socket options on a given socket
+glob File expand filenames using wildcards
+gmtime Time convert UNIX time into record or string using Greenwich time
+goto Flow create spaghetti code
+grep LIST locate elements in a list test true against a given criterion
+hex Math,String convert a string to a hexadecimal number
+import Modules,Namespace patch a module's namespace into your own
+index String find a substring within a string
+int Math get the integer portion of a number
+ioctl File system-dependent device control system call
+join LIST join a list into a string using a separator
+keys HASH retrieve list of indices from a hash
+kill Process send a signal to a process or process group
+last Flow exit a block prematurely
+lc String return lower-case version of a string
+lcfirst String return a string with just the next letter in lower case
+length String return the number of bytes in a string
+link File create a hard link in the filesytem
+listen Socket register your socket as a server
+local Misc,Namespace create a temporary value for a global variable (dynamic scoping)
+localtime Time convert UNIX time into record or string using local time
+log Math retrieve the natural logarithm for a number
+lstat File stat a symbolic link
+m// Regexp match a string with a regular expression pattern
+map LIST apply a change to a list to get back a new list with the changes
+mkdir File create a directory
+msgctl SysV SysV IPC message control operations
+msgget SysV get SysV IPC message queue
+msgrcv SysV receive a SysV IPC message from a message queue
+msgsnd SysV send a SysV IPC message to a message queue
+my Misc,Namespace declare and assign a local variable (lexical scoping)
+next Flow iterate a block prematurely
+no Modules unimport some module symbols or semantics at compile time
+package Modules,Objects,Namespace declare a separate global namespace
+oct String,Math convert a string to an octal number
+open File open a file, pipe, or descriptor
+opendir File open a directory
+ord String find a character's numeric representation
+pack Binary,String convert a list into a binary representation
+pipe Process open a pair of connected filehandles
+pop ARRAY remove the last element from an array and return it
+pos Regexp find or set the offset for the last/next m//g search
+print I/O output a list to a filehandle
+printf I/O output a formatted list to a filehandle
+push ARRAY append one or more elements to an array
+q/STRING/ String singly quote a string
+qq/STRING/ String doubly quote a string
+quotemeta Regexp quote regular expression magic characters
+qw/STRING/ LIST quote a list of words
+qx/STRING/ Process backquote quote a string
+rand Math retrieve the next pseudorandom number
+read I/O,Binary fixed-length buffered input from a filehandle
+readdir I/O get a directory from a directory handle
+readlink File determine where a symbolic link is pointing
+recv Socket receive a message over a Socket
+redo Flow start this loop iteration over again
+ref Objects find out the type of thing being referenced
+rename File change a filename
+require Modules load in external functions from a library at runtime
+reset Misc clear all variables of a given name
+return Flow get out of a function early
+reverse String,LIST flip a string or a list
+rewinddir I/O reset directory handle
+rindex String right-to-left substring search
+rmdir File remove a directory
+s/// Regexp replace a pattern with a string
+scalar Misc force a scalar context
+seek I/O reposition file pointer for random-access I/O
+seekdir I/O reposition directory pointer
+select I/O reset default output or do I/O multiplexing
+semctl SysV SysV semaphore control operations
+semget SysV get set of SysV semaphores
+semop SysV SysV semaphore operations
+send Socket send a message over a socket
+setgrent User prepare group file for use
+sethostent Network prepare hosts file for use
+setnetent Network prepare networks file for use
+setpgrp Process set the process group of a process
+setpriority Process set a process's nice value
+setprotoent Network prepare protocols file for use
+setpwent User prepare passwd file for use
+setservent Network prepare services file for use
+setsockopt Socket set some socket options
+shift ARRAY remove the first element of an array, and return it
+shmctl SysV SysV shared memory operations
+shmget SysV get SysV shared memory segment identifier
+shmread SysV read SysV shared memory
+shmwrite SysV write SysV shared memory
+shutdown Socket close down just half of a socket connection
+sin Math return the sin of a number
+sleep Process block for some number of seconds
+socket Socket create a socket
+socketpair Socket create a pair of sockets
+sort LIST sort a list of values
+splice ARRAY add or remove elements anywhere in an array
+split Regexp split up a string using a regexp delimiter
+sprintf String formatted print into a string
+sqrt Math square root function
+srand Math seed the random number generator
+stat File get a file's status information
+study Regexp optimize input data for repeated searches
+sub Flow declare a subroutine, possibly anonymously
+substr String get or alter a portion of a stirng
+symlink File create a symbolic link to a file
+syscall I/O,Binary execute an arbitrary system call
+sysread I/O,Binary fixed-length unbuffered input from a filehandle
+system Process run a separate program
+syswrite I/O,Binary fixed-length unbuffered output to a filehandle
+tell I/O get current seekpointer on a filehandle
+telldir I/O get current seekpointer on a directory handle
+tie Objects bind a variable to an object class
+time Time return number of seconds since 1970
+times Process,Time return elapsed time for self and child processes
+tr/// String transliterate a string
+truncate I/O shorten a file
+uc String return upper-case version of a string
+ucfirst String return a string with just the next letter in upper case
+umask File set file creation mode mask
+undef Misc remove a variable or function definition
+unlink File remove one link to a file
+unpack Binary,LIST convert binary structure into normal perl variables
+unshift ARRAY prepend more elements to the beginning of a list
+untie Objects break a tie binding to a variable
+use Modules,Namespace load a module and import its namespace
+use Objects load in a module at compile time
+utime File set a file's last access and modify times
+values HASH return a list of the values in a hash
+vec Binary test or set particular bits in a string
+wait Process wait for any child process to die
+waitpid Process wait for a particular child process to die
+wantarray Misc,Flow get list vs array context of current subroutine call
+warn I/O print debugging info
+write I/O print a picture record
+y/// String transliterate a string
--- /dev/null
+POSIX::_exit POSIX terminate a process
+POSIX::abort POSIX generate a fault
+POSIX::abs POSIX integer absolute value
+POSIX::access POSIX determine accessibility of file
+POSIX::acos POSIX trigonometric functions
+POSIX::alarm POSIX schedule signal after specified time
+POSIX::asctime POSIX convert date and time
+POSIX::asin POSIX trigonometric functions
+POSIX::assert POSIX program verification
+POSIX::atan2 POSIX trigonometric functions
+POSIX::atan POSIX trigonometric functions
+POSIX::atof POSIX convert string to double-precision number
+POSIX::atoi POSIX convert string to integer
+POSIX::atol POSIX convert string to integer
+POSIX::bsearch POSIX binary search a sorted table
+POSIX::calloc POSIX memory allocator
+POSIX::ceil POSIX round to integral value in floating-point or integer format
+POSIX::chdir POSIX change current working directory
+POSIX::chmod POSIX change mode of file
+POSIX::chown POSIX change owner and group of a file
+POSIX::clearerr POSIX stream status inquiries
+POSIX::clock POSIX report CPU time used
+POSIX::close POSIX delete a descriptor
+POSIX::closedir POSIX directory operations
+POSIX::cos POSIX trigonometric functions
+POSIX::cosh POSIX hyperbolic functions
+POSIX::creat POSIX create a new file
+POSIX::ctermid POSIX generate filename for terminal
+POSIX::ctime POSIX convert date and time
+POSIX::cuserid POSIX get character login name of the user
+POSIX::dup2 POSIX duplicate a descriptor
+POSIX::dup POSIX duplicate a descriptor
+POSIX::errno POSIX system error messages
+POSIX::execl POSIX execute a file
+POSIX::execle POSIX execute a file
+POSIX::execlp POSIX execute a file
+POSIX::execv POSIX execute a file
+POSIX::execve POSIX execute a file
+POSIX::execvp POSIX execute a file
+POSIX::exit POSIX terminate a process after performing cleanup
+POSIX::exp POSIX exponential, logarithm, power
+POSIX::fabs POSIX appendix and related miscellaneous functions for IEEE arithmetic
+POSIX::fclose POSIX close or flush a stream
+POSIX::fcntl POSIX file control
+POSIX::fdopen POSIX open a stream
+POSIX::feof POSIX stream status inquiries
+POSIX::ferror POSIX stream status inquiries
+POSIX::fflush POSIX close or flush a stream
+POSIX::fgetc POSIX get character or integer from stream
+POSIX::fgets POSIX get a string from a stream
+POSIX::fileno POSIX stream status inquiries
+POSIX::floor POSIX round to integral value in floating-point or integer format
+POSIX::fmod POSIX appendix and related miscellaneous functions for IEEE arithmetic
+POSIX::fopen POSIX open a stream
+POSIX::fork POSIX create a new process
+POSIX::fpathconf POSIX query file system related limits and options
+POSIX::fprintf POSIX formatted output conversion
+POSIX::fputc POSIX put character or word on a stream
+POSIX::fputs POSIX put a string on a stream
+POSIX::fread POSIX buffered binary input/output
+POSIX::free POSIX memory allocator
+POSIX::freopen POSIX open a stream
+POSIX::frexp POSIX traditional UNIX functions
+POSIX::fscanf POSIX formatted input conversion
+POSIX::fseek POSIX reposition a stream
+POSIX::fstat POSIX get file status
+POSIX::ftell POSIX reposition a stream
+POSIX::fwrite POSIX buffered binary input/output
+POSIX::getc POSIX get character or integer from stream
+POSIX::getchar POSIX get character or integer from stream
+POSIX::getcwd POSIX get pathname of current working directory
+POSIX::getegid POSIX get group identity
+POSIX::getenv POSIX return value for environment name
+POSIX::geteuid POSIX get user identity
+POSIX::getgid POSIX get group identity
+POSIX::getgrgid POSIX get group file entry
+POSIX::getgrnam POSIX get group file entry
+POSIX::getgroups POSIX get or set supplementary group IDs
+POSIX::getlogin POSIX get login name
+POSIX::getpgrp POSIX return or set the process group of a process
+POSIX::getpid POSIX get process identification
+POSIX::getppid POSIX get process identification
+POSIX::getpwnam POSIX get password file entry
+POSIX::getpwuid POSIX get password file entry
+POSIX::gets POSIX get a string from a stream
+POSIX::getuid POSIX get user identity
+POSIX::gmtime POSIX convert date and time
+POSIX::isalnum POSIX character classification and conversion macros and functions
+POSIX::isalpha POSIX character classification and conversion macros and functions
+POSIX::isatty POSIX find name of a terminal
+POSIX::iscntrl POSIX character classification and conversion macros and functions
+POSIX::isdigit POSIX character classification and conversion macros and functions
+POSIX::isgraph POSIX character classification and conversion macros and functions
+POSIX::islower POSIX character classification and conversion macros and functions
+POSIX::isprint POSIX character classification and conversion macros and functions
+POSIX::ispunct POSIX character classification and conversion macros and functions
+POSIX::isspace POSIX character classification and conversion macros and functions
+POSIX::isupper POSIX character classification and conversion macros and functions
+POSIX::isxdigit POSIX character classification and conversion macros and functions
+POSIX::kill POSIX send a signal to a process or a group of processes
+POSIX::ldexp POSIX traditional UNIX functions
+POSIX::link POSIX make a hard link to a file
+POSIX::localeconv POSIX get numeric and monetary formatting conventions
+POSIX::localtime POSIX convert date and time
+POSIX::log10 POSIX exponential, logarithm, power
+POSIX::log POSIX exponential, logarithm, power
+POSIX::longjmp POSIX non-local goto
+POSIX::lseek POSIX move read/write pointer
+POSIX::malloc POSIX memory allocator
+POSIX::mblen POSIX multibyte character handling
+POSIX::mbstowcs POSIX multibyte character handling
+POSIX::mbtowc POSIX multibyte character handling
+POSIX::memchr POSIX memory operations
+POSIX::memcmp POSIX memory operations
+POSIX::memcpy POSIX memory operations
+POSIX::memset POSIX memory operations
+POSIX::mkdir POSIX make a directory file
+POSIX::mkfifo POSIX make a special file
+POSIX::modf POSIX traditional UNIX functions
+POSIX::nice POSIX change nice value of a process
+POSIX::open POSIX open or create a file for reading or writing
+POSIX::opendir POSIX directory operations
+POSIX::pathconf POSIX query file system related limits and options
+POSIX::pause POSIX stop until signal
+POSIX::perror POSIX system error messages
+POSIX::pipe POSIX create an interprocess communication channel
+POSIX::pow POSIX exponential, logarithm, power
+POSIX::pow POSIX multiple precision integer arithmetic
+POSIX::printf POSIX formatted output conversion
+POSIX::putc POSIX put character or word on a stream
+POSIX::putchar POSIX put character or word on a stream
+POSIX::puts POSIX put a string on a stream
+POSIX::qsort POSIX quicker sort
+POSIX::rand POSIX simple random number generator
+POSIX::read POSIX read input
+POSIX::readdir POSIX directory operations
+POSIX::realloc POSIX memory allocator
+POSIX::rename POSIX change the name of a file
+POSIX::rewind POSIX reposition a stream
+POSIX::rewinddir POSIX directory operations
+POSIX::rmdir POSIX remove a directory file
+POSIX::scanf POSIX formatted input conversion
+POSIX::setbuf POSIX assign buffering to a stream
+POSIX::setgid POSIX set user and group ID
+POSIX::setjmp POSIX non-local goto
+POSIX::setlocale POSIX set international environment
+POSIX::setpgid POSIX set process group ID for job control
+POSIX::setsid POSIX create session and set process group ID
+POSIX::setuid POSIX set user and group ID
+POSIX::setvbuf POSIX assign buffering to a stream
+POSIX::sigaction POSIX examine and change signal action
+POSIX::siglongjmp POSIX non-local goto
+POSIX::sigpending POSIX examine pending signals
+POSIX::sigprocmask POSIX examine and change blocked signals
+POSIX::sigsetjmp POSIX non-local goto
+POSIX::sigsuspend POSIX automatically release blocked signals and wait for interrupt
+POSIX::sin POSIX trigonometric functions
+POSIX::sinh POSIX hyperbolic functions
+POSIX::sleep POSIX suspend execution for interval
+POSIX::sprintf POSIX formatted output conversion
+POSIX::sqrt POSIX cube root, square root
+POSIX::srand POSIX simple random number generator
+POSIX::sscanf POSIX formatted input conversion
+POSIX::stat POSIX get file status
+POSIX::strcat POSIX string operations
+POSIX::strchr POSIX string operations
+POSIX::strcmp POSIX string operations
+POSIX::strcoll POSIX compare or transform strings using collating information
+POSIX::strcpy POSIX string operations
+POSIX::strcspn POSIX string operations
+POSIX::strftime POSIX convert date and time
+POSIX::strlen POSIX string operations
+POSIX::strncat POSIX string operations
+POSIX::strncmp POSIX string operations
+POSIX::strncpy POSIX string operations
+POSIX::strpbrk POSIX string operations
+POSIX::strrchr POSIX string operations
+POSIX::strspn POSIX string operations
+POSIX::strstr POSIX string operations
+POSIX::strtod POSIX convert string to double-precision number
+POSIX::strtok POSIX string operations
+POSIX::strtol POSIX convert string to integer
+POSIX::strxfrm POSIX compare or transform strings using collating information
+POSIX::sysconf POSIX query system related limits, values, options
+POSIX::system POSIX issue a shell command
+POSIX::tan POSIX trigonometric functions
+POSIX::tanh POSIX hyperbolic functions
+POSIX::tcdrain POSIX get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcflow POSIX get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcflush POSIX get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcgetpgrp POSIX get, set foreground process group ID
+POSIX::tcsendbreak POSIX get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcsetpgrp POSIX get, set foreground process group ID
+POSIX::tell POSIX move read/write pointer
+POSIX::time POSIX get date and time
+POSIX::times POSIX get process times
+POSIX::tmpfile POSIX create a temporary file
+POSIX::tmpnam POSIX create a name for a temporary file
+POSIX::tolower POSIX character classification and conversion macros and functions
+POSIX::toupper POSIX character classification and conversion macros and functions
+POSIX::ttyname POSIX find name of a terminal
+POSIX::tzset POSIX convert date and time
+POSIX::umask POSIX set file creation mode mask
+POSIX::uname POSIX get information about current system
+POSIX::ungetc POSIX push character back into input stream
+POSIX::unlink POSIX remove directory entry
+POSIX::utime POSIX set file times
+POSIX::vfprintf POSIX print formatted output of a varargs argument list
+POSIX::vprintf POSIX print formatted output of a varargs argument list
+POSIX::vsprintf POSIX print formatted output of a varargs argument list
+POSIX::wait POSIX wait for process to terminate or stop, examine returned status
+POSIX::waitpid POSIX wait for process to terminate or stop, examine returned status
+POSIX::wcstombs POSIX multibyte character handling
+POSIX::wctomb POSIX multibyte character handling
+POSIX::write POSIX write output
--- /dev/null
+use File::Find;
+use Cwd;
+
+@pods = qw{
+ perl perldata perlsyn perlop perlre perlrun perlfunc perlvar
+ perlsub perlmod perlref perldsc perllol perlobj perltie
+ perlbot perldebug perldiag perlform perlipc perlsec perltrap
+ perlstyle perlxs perlxstut perlguts perlcall perlembed perlpod
+ perlbook
+ };
+for (@pods) { s/$/.pod/ }
+
+$/ = '';
+@ARGV = @pods;
+
+($_= <<EOPOD2B) =~ s/^\t//gm && print;
+
+ =head1 NAME
+
+ perltoc - perl documentation table of contents
+
+ =head1 DESCRIPTION
+
+ This page provides a brief table of contents for the rest of the Perl
+ documentation set. It is meant to be be quickly scanned or grepped
+ through to locate the proper section you're looking for.
+
+ =head1 BASIC DOCUMENTATION
+
+EOPOD2B
+
+podset(@pods);
+
+find \&getpods => qw(../lib ../ext);
+sub getpods {
+ if (/\.p(od|m)$/) {
+ my $file = $File::Find::name;
+ die "tut $name" if $file =~ /TUT/;
+ unless (open (F, "< $_\0")) {
+ warn "bogus <$file>: $!";
+ system "ls", "-l", $file;
+ } else {
+ my $line;
+ while ($line = <F>) {
+ if ($line =~ /^=head1\s+NAME\b/) {
+ push @modpods, $file;
+ #warn "GOOD $file\n";
+ return;
+ }
+ }
+ warn "EVIL $file\n";
+ }
+ }
+}
+
+die "no pods" unless @modpods;
+
+for (@modpods) {
+ #($name) = /(\w+)\.p(m|od)$/;
+ $name = path2modname($_);
+ if ($name =~ /^[a-z]/) {
+ push @pragmata, $_;
+ } else {
+ if ($done{$name}++) {
+ # warn "already did $_\n";
+ next;
+ }
+ push @modules, $_;
+ push @modname, $name;
+ }
+}
+
+($_= <<EOPOD2B) =~ s/^\t//gm && print;
+
+
+
+ =head1 PRAGMA DOCUMENTATION
+
+EOPOD2B
+
+podset(sort @pragmata);
+
+($_= <<EOPOD2B) =~ s/^\t//gm && print;
+
+
+
+ =head1 MODULE DOCUMENTATION
+
+EOPOD2B
+
+podset( @modules[ sort { $modname[$a] cmp $modname[$b] } 0 .. $#modules ] );
+
+($_= <<EOPOD2B) =~ s/^\t//gm;
+
+
+ =head1 AUXILIARY DOCUMENTATION
+
+ Here should be listed all the extra program's docs, but they
+ don't all have man pages yet:
+
+ =item a2p
+
+ =item s2p
+
+ =item find2perl
+
+ =item h2ph
+
+ =item c2ph
+
+ =item h2xs
+
+ =item xsubpp
+
+ =item pod2man
+
+ =item wrapsuid
+
+
+ =head1 AUTHOR
+
+ Larry Wall E<lt><F<lwall\@netlabs.com>E<gt>, with the help of oodles
+ of other folks.
+
+
+EOPOD2B
+print;
+
+exit;
+
+sub podset {
+ local @ARGV = @_;
+
+ while(<>) {
+ if (s/^=head1 (NAME)\s*/=head2 /) {
+ $pod = path2modname($ARGV);
+ sub path2modname {
+ local $_ = shift;
+ s/\.p(m|od)$//;
+ s-.*?/(lib|ext)/--;
+ s-/-::-g;
+ s/(\w+)::\1/$1/;
+ return $_;
+ }
+ unitem(); unhead2();
+ print "\n \n\n=head2 ";
+ $_ = <>;
+ if ( /^\s*$pod\b/ ) {
+ print;
+ } else {
+ s/^/$pod, /;
+ print;
+ }
+ next;
+ }
+ if (s/^=head1 (.*)/=item $1/) {
+ unitem(); unhead2();
+ print; nl(); next;
+ }
+ if (s/^=head2 (.*)/=item $1/) {
+ unitem();
+ print "=over\n\n" unless $inhead2;
+ $inhead2 = 1;
+ print; nl(); next;
+
+ }
+ if (s/^=item (.*)\n/$1/) {
+ next if $pod eq 'perldiag';
+ s/^\s*\*\s*$// && next;
+ s/^\s*\*\s*//;
+ s/\s+$//;
+ next if /^[\d.]+$/;
+ next if $pod eq 'perlmod' && /^ftp:/;
+ ##print "=over\n\n" unless $initem;
+ print ", " if $initem;
+ $initem = 1;
+ s/\.$//;
+ print; next;
+ }
+ }
+
+}
+
+sub unhead2 {
+ if ($inhead2) {
+ print "\n\n=back\n\n";
+ }
+ $inhead2 = 0;
+ $initem = 0;
+}
+
+sub unitem {
+ if ($initem) {
+ print "\n\n";
+ ##print "\n\n=back\n\n";
+ }
+ $initem = 0;
+}
+
+sub nl {
+ print "\n";
+}
of sections:
perl Perl overview (this section)
+ perltoc Perl documentation table of contents
perldata Perl data structures
perlsyn Perl syntax
perlop Perl operators and precedence
perldsc Perl data structures intro
perllol Perl data structures: lists of lists
perlobj Perl objects
+ perltie Perl objects hidden behind simple variables
perlbot Perl OO tricks and examples
perldebug Perl debugging
perldiag Perl diagnostic messages
perlxstut Perl XS tutorial
perlguts Perl internal functions for those doing extensions
perlcall Perl calling conventions from C
- perlovl Perl overloading semantics
perlembed Perl how to embed perl in your C or C++ app
perlpod Perl plain old documentation
perlbook Perl book information
component of your PATH may be longer than 255 if you use B<-S>. A regular
expression may not compile to more than 32767 bytes internally.
-See the perl bugs database at L<http://perl.com/perl/bugs/>.
+See the perl bugs database at F<http://perl.com/perl/bugs/>. You may
+mail your bug reports (be sure to include full configuration information
+as output by the myconfig program in the perl source tree) to
+F<perlbug@perl.com>.
Perl actually stands for Pathologically Eclectic Rubbish Lister, but
don't tell anyone I said that.
perlbot - Bag'o Object Tricks (the BOT)
-=head1 INTRODUCTION
+=head1 DESCRIPTION
The following collection of tricks and hints is intended to whet curious
appetites about such things as the use of instance variables and the
=head1 NAME
-perldata - Perl data structures
+perldata - Perl data types
=head1 DESCRIPTION
Names that start with a digit may only contain more digits. Names
which do not start with a letter, underscore, or digit are limited to
-one character, e.g. "$%" or "$$". (Most of these one character names
-have a predefined significance to Perl. For instance, $$ is the
+one character, e.g. C<$%> or C<$$>. (Most of these one character names
+have a predefined significance to Perl. For instance, C<$$> is the
current process id.)
=head2 Context
use it as if it were defined, but prior to that you can use the
defined() operator to determine whether the value is defined or not.
-To find out whether a given string is a valid non-zero number, it's usally
+To find out whether a given string is a valid non-zero number, it's usually
enough to test it against both numeric 0 and also lexical "0" (although
this will cause B<-w> noises). That's because strings that aren't
numbers count as 0, just as the do in I<awk>:
warn "That doesn't look like a number";
}
+That's usually preferable because otherwise you won't treat IEEE notations
+like C<NaN> or C<Infinity> properly. At other times you might prefer to
+use a regular expression to check whether data is numeric. See L<perlre>
+for details on regular expressions.
+
+ warn "has nondigits" if /\D/;
+ warn "not a whole number" unless /^\d+$/;
+ warn "not an integer" unless /^[+-]?\d+$/
+ warn "not a decimal number" unless /^[+-]?\d+\.?\d*$/
+ warn "not a C float"
+ unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
+
The length of an array is a scalar value. You may find the length of
array @days by evaluating C<$#days>, as in B<csh>. (Actually, it's not
the length of the array, it's the subscript of the last element, since
text is ignored, but may be read via the DATA filehandle. (The DATA
filehandle may read data only from the main script, but not from any
required file or evaluated string.) The two control characters ^D and
-^Z are synonyms for __END__ (or __DATA__ in a module).
+^Z are synonyms for __END__ (or __DATA__ in a module; see L<SelfLoader> for
+details on __DATA__).
A word that has no other interpretation in the grammar will
be treated as if it were a quoted string. These are known as
linebreak => 'true',
labels => \%labels
);
+
+Note that just because a hash is initialized in that order doesn't
+mean that it comes out in that order. See L<perlfunc/sort> for examples
+of how to arrange for an output ordering.
+
+=head2 Typeglobs and FileHandles
+
+Perl uses an internal type called a I<typeglob> to hold an entire
+symbol table entry. The type prefix of a typeglob is a C<*>, because
+it represents all types. This used to be the preferred way to
+pass arrays and hashes by reference into a function, but now that
+we have real references, this is seldom needed.
+
+One place where you still use typeglobs (or references thereto)
+is for passing or storing filehandles. If you want to save away
+a filehandle, do it this way:
+
+ $fh = *STDOUT;
+
+or perhaps as a real reference, like this:
+
+ $fh = \*STDOUT;
+
+This is also the way to create a local filehandle. For example:
+
+ sub newopen {
+ my $path = shift;
+ local *FH; # not my!
+ open (FH, $path) || return undef;
+ return \*FH;
+ }
+ $fh = newopen('/etc/passwd');
+
+See L<perlref>, L<perlsub>, and L<perlmod/"Symbols Tables"> for more
+discussion on typeglobs. See L<perlfunc/open> for other ways of
+generating filehandles.
(F) A fatal error (trappable).
(P) An internal error you should never see (trappable).
(X) A very fatal error (non-trappable).
+ (A) An alien error message (not generated by Perl).
Optional warnings are enabled by using the B<-w> switch. Warnings may
be captured by setting C<$^Q> to a reference to a routine that will be
(F) The final summary message when a C<perl -c> succeeds.
+=item %s: Command not found.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
+=item %s: Expression syntax.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
+=item %s: Undefined variable.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
+=item %s: not found
+
+(A) You've accidentally run your script through the Bourne shell
+instead of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
=item B<-P> not allowed for setuid/setgid script
(F) The script would have to be opened by the C preprocessor by name,
(P) An internal request asked to add a hash entry to something that
wasn't a symbol table entry.
+=item Badly places ()'s
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
=item BEGIN failed--compilation aborted
(F) An untrapped exception was raised while executing a BEGIN subroutine.
=item Precedence problem: open %s should be open(%s)
(S) The old irregular construct
-
+
open FOO || die;
is now misinterpreted as
C<perl -c> repeatedly, chopping away half the program each time to see
if the error went away. Sort of the cybernetic version of S<20 questions>.
+=item syntax error at line %d: `%s' unexpected
+
+(A) You've accidentally run your script through the Bourne shell
+instead of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
=item System V IPC is not implemented on this machine
(F) You tried to do something with a function beginning with "sem", "shm"
(F) There has to be at least one argument to syscall() to specify the
system call to call, silly dilly.
+=item Too many ('s
+
+=item Too many )'s
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
=item Too many args to syscall
(F) Perl only supports a maximum of 14 args to syscall().
by that module. It usually means you put the wrong funny character
on the front of your variable.
+=item Variable syntax.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl. Check the <#!> line, or manually feed your script
+into Perl yourself.
+
=item Warning: unable to close filehandle %s properly.
(S) The implicit close() done by an open() got an error indication on the
-=head1 TITLE
+=head1 NAME
-perldsc - Manipulating Complex Data Structures in Perl
+perldsc - Perl Data Structures Cookbook
-=head1 INTRODUCTION
+=head1 DESCRIPTION
The single feature most sorely lacking in the Perl programming language
prior to its 5.0 release was complex data structures. Even without direct
There's also a lower-case B<x> command which is nearly the same.
+=head1 CODE EXAMPLES
+
+Presented with little comment (these will get their own man pages someday)
+here are short code examples illustrating access of various
+types of data structures.
+
+=head1 LISTS OF LISTS
+
+=head2 Declaration of a LIST OF LISTS
+
+ @LoL = (
+ [ "fred", "barney" ],
+ [ "george", "jane", "elroy" ],
+ [ "homer", "marge", "bart" ],
+ );
+
+=head2 Generation of a LIST OF LISTS
+
+ # reading from file
+ while ( <> ) {
+ push @LoL, [ split ];
+
+
+ # calling a function
+ for $i ( 1 .. 10 ) {
+ $LoL[$i] = [ somefunc($i) ];
+
+
+ # using temp vars
+ for $i ( 1 .. 10 ) {
+ @tmp = somefunc($i);
+ $LoL[$i] = [ @tmp ];
+
+
+ # add to an existing row
+ push @{ $LoL[0] }, "wilma", "betty";
+
+=head2 Access and Printing of a LIST OF LISTS
+
+ # one element
+ $LoL[0][0] = "Fred";
+
+ # another element
+ $LoL[1][1] =~ s/(\w)/\u$1/;
+
+ # print the whole thing with refs
+ for $aref ( @LoL ) {
+ print "\t [ @$aref ],\n";
+
+
+ # print the whole thing with indices
+ for $i ( 0 .. $#LoL ) {
+ print "\t [ @{$LoL[$i]} ],\n";
+
+
+ # print the whole thing one at a time
+ for $i ( 0 .. $#LoL ) {
+ for $j ( 0 .. $#{$LoL[$i]} ) {
+ print "elt $i $j is $LoL[$i][$j]\n";
+ }
+
+
+=head1 HASHES OF LISTS
+
+=head2 Declaration of a HASH OF LISTS
+
+ %HoL = (
+ "flintstones" => [ "fred", "barney" ],
+ "jetsons" => [ "george", "jane", "elroy" ],
+ "simpsons" => [ "homer", "marge", "bart" ],
+ );
+
+=head2 Generation of a HASH OF LISTS
+
+ # reading from file
+ # flintstones: fred barney wilma dino
+ while ( <> ) {
+ next unless s/^(.*?):\s*//;
+ $HoL{$1} = [ split ];
+
+
+ # reading from file; more temps
+ # flintstones: fred barney wilma dino
+ while ( $line = <> ) {
+ ($who, $rest) = split /:\s*/, $line, 2;
+ @fields = split ' ', $rest;
+ $HoL{$who} = [ @fields ];
+
+
+ # calling a function that returns a list
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+ $HoL{$group} = [ get_family($group) ];
+
+
+ # likewise, but using temps
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+ @members = get_family($group);
+ $HoL{$group} = [ @members ];
+
+
+ # append new members to an existing family
+ push @{ $HoL{"flintstones"} }, "wilma", "betty";
+
+=head2 Access and Printing of a HASH OF LISTS
+
+ # one element
+ $HoL{flintstones}[0] = "Fred";
+
+ # another element
+ $HoL{simpsons}[1] =~ s/(\w)/\u$1/;
+
+ # print the whole thing
+ foreach $family ( keys %HoL ) {
+ print "$family: @{ $HoL{$family} }\n"
+
+
+ # print the whole thing with indices
+ foreach $family ( keys %HoL ) {
+ print "family: ";
+ foreach $i ( 0 .. $#{ $HoL{$family} ) {
+ print " $i = $HoL{$family}[$i]";
+ }
+ print "\n";
+
+
+ # print the whole thing sorted by number of members
+ foreach $family ( sort { @{$HoL{$b}} <=> @{$HoL{$b}} } keys %HoL ) {
+ print "$family: @{ $HoL{$family} }\n"
+
+ # print the whole thing sorted by number of members and name
+ foreach $family ( sort { @{$HoL{$b}} <=> @{$HoL{$a}} } keys %HoL ) {
+ print "$family: ", join(", ", sort @{ $HoL{$family}), "\n";
+
+=head1 LISTS OF HASHES
+
+=head2 Declaration of a LIST OF HASHES
+
+ @LoH = (
+ {
+ Lead => "fred",
+ Friend => "barney",
+ },
+ {
+ Lead => "george",
+ Wife => "jane",
+ Son => "elroy",
+ },
+ {
+ Lead => "homer",
+ Wife => "marge",
+ Son => "bart",
+ }
+ );
+
+=head2 Generation of a LIST OF HASHES
+
+ # reading from file
+ # format: LEAD=fred FRIEND=barney
+ while ( <> ) {
+ $rec = {};
+ for $field ( split ) {
+ ($key, $value) = split /=/, $field;
+ $rec->{$key} = $value;
+ }
+ push @LoH, $rec;
+
+
+ # reading from file
+ # format: LEAD=fred FRIEND=barney
+ # no temp
+ while ( <> ) {
+ push @LoH, { split /[\s+=]/ };
+
+
+ # calling a function that returns a key,value list, like
+ # "lead","fred","daughter","pebbles"
+ while ( %fields = getnextpairset() )
+ push @LoH, { %fields };
+
+
+ # likewise, but using no temp vars
+ while (<>) {
+ push @LoH, { parsepairs($_) };
+
+
+ # add key/value to an element
+ $LoH[0]{"pet"} = "dino";
+ $LoH[2]{"pet"} = "santa's little helper";
+
+=head2 Access and Printing of a LIST OF HASHES
+
+ # one element
+ $LoH[0]{"lead"} = "fred";
+
+ # another element
+ $LoH[1]{"lead"} =~ s/(\w)/\u$1/;
+
+ # print the whole thing with refs
+ for $href ( @LoH ) {
+ print "{ ";
+ for $role ( keys %$href ) {
+ print "$role=$href->{$role} ";
+ }
+ print "}\n";
+
+
+ # print the whole thing with indices
+ for $i ( 0 .. $#LoH ) {
+ print "$i is { ";
+ for $role ( keys %{ $LoH[$i] } ) {
+ print "$role=$LoH[$i]{$role} ";
+ }
+ print "}\n";
+
+
+ # print the whole thing one at a time
+ for $i ( 0 .. $#LoH ) {
+ for $role ( keys %{ $LoH[$i] } ) {
+ print "elt $i $role is $LoH[$i]{$role}\n";
+ }
+
+=head1 HASHES OF HASHES
+
+=head2 Declaration of a HASH OF HASHES
+
+ %HoH = (
+ "flintstones" => {
+ "lead" => "fred",
+ "pal" => "barney",
+ },
+ "jetsons" => {
+ "lead" => "george",
+ "wife" => "jane",
+ "his boy"=> "elroy",
+ }
+ "simpsons" => {
+ "lead" => "homer",
+ "wife" => "marge",
+ "kid" => "bart",
+ );
+
+=head2 Generation of a HASH OF HASHES
+
+ # reading from file
+ # flintstones: lead=fred pal=barney wife=wilma pet=dino
+ while ( <> ) {
+ next unless s/^(.*?):\s*//;
+ $who = $1;
+ for $field ( split ) {
+ ($key, $value) = split /=/, $field;
+ $HoH{$who}{$key} = $value;
+ }
+
+
+ # reading from file; more temps
+ while ( <> ) {
+ next unless s/^(.*?):\s*//;
+ $who = $1;
+ $rec = {};
+ $HoH{$who} = $rec;
+ for $field ( split ) {
+ ($key, $value) = split /=/, $field;
+ $rec->{$key} = $value;
+ }
+
+
+ # calling a function that returns a key,value list, like
+ # "lead","fred","daughter","pebbles"
+ while ( %fields = getnextpairset() )
+ push @a, { %fields };
+
+
+ # calling a function that returns a key,value hash
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+ $HoH{$group} = { get_family($group) };
+
+
+ # likewise, but using temps
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+ %members = get_family($group);
+ $HoH{$group} = { %members };
+
+
+ # append new members to an existing family
+ %new_folks = (
+ "wife" => "wilma",
+ "pet" => "dino";
+ );
+ for $what (keys %new_folks) {
+ $HoH{flintstones}{$what} = $new_folks{$what};
+
+
+=head2 Access and Printing of a HASH OF HASHES
+
+ # one element
+ $HoH{"flintstones"}{"wife"} = "wilma";
+
+ # another element
+ $HoH{simpsons}{lead} =~ s/(\w)/\u$1/;
+
+ # print the whole thing
+ foreach $family ( keys %HoH ) {
+ print "$family: ";
+ for $role ( keys %{ $HoH{$family} } {
+ print "$role=$HoH{$family}{$role} ";
+ }
+ print "}\n";
+
+
+ # print the whole thing somewhat sorted
+ foreach $family ( sort keys %HoH ) {
+ print "$family: ";
+ for $role ( sort keys %{ $HoH{$family} } {
+ print "$role=$HoH{$family}{$role} ";
+ }
+ print "}\n";
+
+
+ # print the whole thing sorted by number of members
+ foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$b}} } keys %HoH ) {
+ print "$family: ";
+ for $role ( sort keys %{ $HoH{$family} } {
+ print "$role=$HoH{$family}{$role} ";
+ }
+ print "}\n";
+
+
+ # establish a sort order (rank) for each role
+ $i = 0;
+ for ( qw(lead wife son daughter pal pet) ) { $rank{$_} = ++$i }
+
+ # now print the whole thing sorted by number of members
+ foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$b}} } keys %HoH ) {
+ print "$family: ";
+ # and print these according to rank order
+ for $role ( sort { $rank{$a} <=> $rank{$b} keys %{ $HoH{$family} } {
+ print "$role=$HoH{$family}{$role} ";
+ }
+ print "}\n";
+
+
+=head1 MORE ELABORATE RECORDS
+
+=head2 Declaration of MORE ELABORATE RECORDS
+
+Here's a sample showing how to create and use a record whose fields are of
+many different sorts:
+
+ $rec = {
+ STRING => $string,
+ LIST => [ @old_values ],
+ LOOKUP => { %some_table },
+ FUNC => \&some_function,
+ FANON => sub { $_[0] ** $_[1] },
+ FH => \*STDOUT,
+ };
+
+ print $rec->{STRING};
+
+ print $rec->{LIST}[0];
+ $last = pop @ { $rec->{LIST} };
+
+ print $rec->{LOOKUP}{"key"};
+ ($first_k, $first_v) = each %{ $rec->{LOOKUP} };
+
+ $answer = &{ $rec->{FUNC} }($arg);
+ $answer = &{ $rec->{FANON} }($arg1, $arg2);
+
+ # careful of extra block braces on fh ref
+ print { $rec->{FH} } "a string\n";
+
+ use FileHandle;
+ $rec->{FH}->autoflush(1);
+ $rec->{FH}->print(" a string\n");
+
+=head2 Declaration of a HASH OF COMPLEX RECORDS
+
+ %TV = (
+ "flintstones" => {
+ series => "flintstones",
+ nights => [ qw(monday thursday friday) ];
+ members => [
+ { name => "fred", role => "lead", age => 36, },
+ { name => "wilma", role => "wife", age => 31, },
+ { name => "pebbles", role => "kid", age => 4, },
+ ],
+ },
+
+ "jetsons" => {
+ series => "jetsons",
+ nights => [ qw(wednesday saturday) ];
+ members => [
+ { name => "george", role => "lead", age => 41, },
+ { name => "jane", role => "wife", age => 39, },
+ { name => "elroy", role => "kid", age => 9, },
+ ],
+ },
+
+ "simpsons" => {
+ series => "simpsons",
+ nights => [ qw(monday) ];
+ members => [
+ { name => "homer", role => "lead", age => 34, },
+ { name => "marge", role => "wife", age => 37, },
+ { name => "bart", role => "kid", age => 11, },
+ ],
+ },
+ );
+
+=head2 Generation of a HASH OF COMPLEX RECORDS
+
+ # reading from file
+ # this is most easily done by having the file itself be
+ # in the raw data format as shown above. perl is happy
+ # to parse complex datastructures if declared as data, so
+ # sometimes it's easiest to do that
+
+ # here's a piece by piece build up
+ $rec = {};
+ $rec->{series} = "flintstones";
+ $rec->{nights} = [ find_days() ];
+
+ @members = ();
+ # assume this file in field=value syntax
+ while () {
+ %fields = split /[\s=]+/;
+ push @members, { %fields };
+ }
+ $rec->{members} = [ @members ];
+
+ # now remember the whole thing
+ $TV{ $rec->{series} } = $rec;
+
+ ###########################################################
+ # now, you might want to make interesting extra fields that
+ # include pointers back into the same data structure so if
+ # change one piece, it changes everywhere, like for examples
+ # if you wanted a {kids} field that was an array reference
+ # to a list of the kids' records without having duplicate
+ # records and thus update problems.
+ ###########################################################
+ foreach $family (keys %TV) {
+ $rec = $TV{$family}; # temp pointer
+ @kids = ();
+ for $person ( @{$rec->{members}} ) {
+ if ($person->{role} =~ /kid|son|daughter/) {
+ push @kids, $person;
+ }
+ }
+ # REMEMBER: $rec and $TV{$family} point to same data!!
+ $rec->{kids} = [ @kids ];
+ }
+
+ # you copied the list, but the list itself contains pointers
+ # to uncopied objects. this means that if you make bart get
+ # older via
+
+ $TV{simpsons}{kids}[0]{age}++;
+
+ # then this would also change in
+ print $TV{simpsons}{members}[2]{age};
+
+ # because $TV{simpsons}{kids}[0] and $TV{simpsons}{members}[2]
+ # both point to the same underlying anonymous hash table
+
+ # print the whole thing
+ foreach $family ( keys %TV ) {
+ print "the $family";
+ print " is on during @{ $TV{$family}{nights} }\n";
+ print "its members are:\n";
+ for $who ( @{ $TV{$family}{members} } ) {
+ print " $who->{name} ($who->{role}), age $who->{age}\n";
+ }
+ print "it turns out that $TV{$family}{'lead'} has ";
+ print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
+ print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
+ print "\n";
+ }
+
=head1 SEE ALSO
-perlref(1), perldata(1)
+L<perlref>, L<perllol>, L<perldata>, L<perlobj>
=head1 AUTHOR
Tom Christiansen E<lt>F<tchrist@perl.com>E<gt>
Last update:
-Sat Oct 7 22:41:09 MDT 1995
+Tue Dec 12 09:20:26 MST 1995
=head1 NAME
-perlembed - how to embed perl in your C or C++ app
+perlembed - how to embed perl in your C program
=head1 DESCRIPTION
-Look at perlmain.c, and do something like that.
+=head2 PREAMBLE
+
+Do you want to:
+
+=over 5
+
+=item B<Use C from Perl?>
+
+Read L<perlcall> and L<perlxs>.
+
+=item B<Use a UNIX program from Perl?>
+
+Read about backquotes and L<perlfunc/system> and L<perlfunc/exec>.
+
+=item B<Use Perl from Perl?>
+
+Read about L<perlfunc/do> and L<perlfunc/eval> and L<perlmod/use>
+and L<perlmod/require>.
+
+=item B<Use C from C?>
+
+Rethink your design.
+
+=item B<Use Perl from C?>
+
+Read on...
+
+=back
+
+=head2 ROADMAP
+
+L<Compiling your C program>
+
+There's one example in each of the five sections:
+
+L<Adding a Perl interpreter to your C program>
+
+L<Calling a Perl subroutine from your C program>
+
+L<Evaluating a Perl statement from your C program>
+
+L<Performing Perl pattern matches and substitutions from your C program>
+
+L<Fiddling with the Perl stack from your C program>
+
+This documentation is UNIX specific.
+
+=head2 Compiling your C program
+
+Every C program that uses Perl must link in the I<perl library>.
+
+What's that, you ask? Perl is itself written in C; the perl library
+is the collection of compiled C programs that were used to create your
+perl executable (I</usr/bin/perl> or equivalent). (Corollary: you
+can't use Perl from your C program unless Perl has been compiled on
+your machine, or installed properly--that's why you shouldn't blithely
+copy Perl executables from machine to machine without also copying the
+I<lib> directory.)
+
+Your C program will--usually--allocate, "run", and deallocate a
+I<PerlInterpreter> object, which is defined in the perl library.
+
+If your copy of Perl is recent enough to contain this documentation
+(5.002 or later), then the perl library (and I<EXTERN.h> and
+I<perl.h>, which you'll also need) will
+reside in a directory resembling this:
+
+ /usr/local/lib/perl5/your_architecture_here/CORE
+
+or perhaps just
+
+ /usr/local/lib/perl5/CORE
+
+or maybe something like
+
+ /usr/opt/perl5/CORE
+
+Execute this statement for a hint about where to find CORE:
+
+ perl -e 'use Config; print $Config{archlib}'
+
+Here's how you might compile the example in the next section,
+L<Adding a Perl interpreter to your C program>,
+on a DEC Alpha running the OSF operating system:
+
+ % cc -o interp interp.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE
+ -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+
+You'll have to choose the appropriate compiler (I<cc>, I<gcc>, et al.) and
+library directory (I</usr/local/lib/...>) for your machine. If your
+compiler complains that certain functions are undefined, or that it
+can't locate I<-lperl>, then you need to change the path following the
+-L. If it complains that it can't find I<EXTERN.h> or I<perl.h>, you need
+to change the path following the -I.
+
+You may have to add extra libraries as well. Which ones?
+Perhaps those printed by
+
+ perl -e 'use Config; print $Config{libs}'
+
+=head2 Adding a Perl interpreter to your C program
+
+In a sense, perl (the C program) is a good example of embedding Perl
+(the language), so I'll demonstrate embedding with I<miniperlmain.c>,
+from the source distribution. Here's a bastardized, non-portable version of
+I<miniperlmain.c> containing the essentials of embedding:
+
+ #include <stdio.h>
+ #include <EXTERN.h> /* from the Perl distribution */
+ #include <perl.h> /* from the Perl distribution */
+
+ static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
+
+ int main(int argc, char **argv, char **env)
+ {
+ my_perl = perl_alloc();
+ perl_construct(my_perl);
+ perl_parse(my_perl, NULL, argc, argv, env);
+ perl_run(my_perl);
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ }
+
+Now compile this program (I'll call it I<interp.c>) into an executable:
+
+ % cc -o interp interp.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE
+ -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+
+After a successful compilation, you'll be able to use I<interp> just
+like perl itself:
+
+ % interp
+ print "Pretty Good Perl \n";
+ print "10890 - 9801 is ", 10890 - 9801;
+ <CTRL-D>
+ Pretty Good Perl
+ 10890 - 9801 is 1089
+
+or
+
+ % interp -e 'printf("%x", 3735928559)'
+ deadbeef
+
+You can also read and execute Perl statements from a file while in the
+midst of your C program, by placing the filename in I<argv[1]> before
+calling I<perl_run()>.
+
+=head2 Calling a Perl subroutine from your C program
+
+To call individual Perl subroutines, you'll need to remove the call to
+I<perl_run()> and replace it with a call to I<perl_call_argv()>.
+
+That's shown below, in a program I'll call I<showtime.c>.
+
+ #include <stdio.h>
+ #include <EXTERN.h>
+ #include <perl.h>
+
+ static PerlInterpreter *my_perl;
+
+ int main(int argc, char **argv, char **env)
+ {
+ my_perl = perl_alloc();
+ perl_construct(my_perl);
+
+ perl_parse(my_perl, NULL, argc, argv, env);
+
+ /*** This replaces perl_run() ***/
+ perl_call_argv("showtime", G_DISCARD | G_NOARGS, argv);
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ }
+
+where I<showtime> is a Perl subroutine that takes no arguments (that's the
+I<G_NOARGS>) and for which I'll ignore the return value (that's the
+I<G_DISCARD>). Those flags, and others, are discussed in L<perlcall>.
+
+I'll define the I<showtime> subroutine in a file called I<showtime.pl>:
+
+ print "I shan't be printed.";
+
+ sub showtime {
+ print time;
+ }
+
+Simple enough. Now compile and run:
+
+ % cc -o showtime showtime.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE
+ -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+
+ % showtime showtime.pl
+ 818284590
+
+yielding the number of seconds that elapsed between January 1, 1970
+(the beginning of the UNIX epoch), and the moment I began writing this
+sentence.
+
+If you want to pass some arguments to the Perl subroutine, or
+you want to access the return value, you'll need to manipulate the
+Perl stack, demonstrated in the last section of this document:
+L<Fiddling with the Perl stack from your C program>
+
+=head2 Evaluating a Perl statement from your C program
+
+NOTE: This section, and the next, employ some very brittle techniques
+for evaluting strings of Perl code. Perl 5.002 contains some nifty
+features that enable A Better Way (such as with L<perlguts/perl_eval_sv>).
+Look for updates to this document soon.
+
+One way to evaluate a Perl string is to define a function (we'll call
+ours I<perl_eval()>) that wraps around Perl's L<perlfunc/eval>.
+
+Arguably, this is the only routine you'll ever need to execute
+snippets of Perl code from within your C program. Your string can be
+as long as you wish; it can contain multiple statements; it can
+use L<perlmod/require> or L<perlfunc/do> to include external Perl
+files.
+
+Our I<perl_eval()> lets us evaluate individual Perl strings, and then
+extract variables for coercion into C types. The following program,
+I<string.c>, executes three Perl strings, extracting an C<int> from
+the first, a C<float> from the second, and a C<char *> from the third.
+
+ #include <stdio.h>
+ #include <EXTERN.h>
+ #include <perl.h>
+
+ static PerlInterpreter *my_perl;
+
+ int perl_eval(char *string)
+ {
+ char *argv[2];
+ argv[0] = string;
+ argv[1] = NULL;
+ perl_call_argv("_eval_", 0, argv);
+ }
+
+ main (int argc, char **argv, char **env)
+ {
+ char *embedding[] = { "", "-e", "sub _eval_ { eval $_[0] }" };
+ STRLEN length;
+
+ my_perl = perl_alloc();
+ perl_construct( my_perl );
+
+ perl_parse(my_perl, NULL, 3, embedding, env);
+
+ /** Treat $a as an integer **/
+ perl_eval("$a = 3; $a **= 2");
+ printf("a = %d\n", SvIV(perl_get_sv("a", FALSE)));
+
+ /** Treat $a as a float **/
+ perl_eval("$a = 3.14; $a **= 2");
+ printf("a = %f\n", SvNV(perl_get_sv("a", FALSE)));
+
+ /** Treat $a as a string **/
+ perl_eval("$a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a); ");
+ printf("a = %s\n", SvPV(perl_get_sv("a", FALSE), length));
+
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ }
+
+All of those strange functions with I<sv> in their names help convert Perl scalars to C types. They're described in L<perlguts>.
+
+If you compile and run I<string.c>, you'll see the results of using
+I<SvIV()> to create an C<int>, I<SvNV()> to create a C<float>, and
+I<SvPV()> to create a string:
+
+ a = 9
+ a = 9.859600
+ a = Just Another Perl Hacker
+
+
+=head2 Performing Perl pattern matches and substitutions from your C program
+
+Our I<perl_eval()> lets us evaluate strings of Perl code, so we can
+define some functions that use it to "specialize" in matches and
+substitutions: I<match()>, I<substitute()>, and I<matches()>.
+
+ char match(char *string, char *pattern);
+
+Given a string and a pattern (e.g. "m/clasp/" or "/\b\w*\b/", which in
+your program might be represented as C<"/\\b\\w*\\b/">),
+returns 1 if the string matches the pattern and 0 otherwise.
+
+
+ int substitute(char *string[], char *pattern);
+
+Given a pointer to a string and an "=~" operation (e.g. "s/bob/robert/g" or
+"tr[A-Z][a-z]"), modifies the string according to the operation,
+returning the number of substitutions made.
+
+ int matches(char *string, char *pattern, char **matches[]);
+
+Given a string, a pattern, and a pointer to an empty array of strings,
+evaluates C<$string =~ $pattern> in an array context, and fills in
+I<matches> with the array elements (allocating memory as it does so),
+returning the number of matches found.
+
+Here's a sample program, I<match.c>, that uses all three:
+
+ #include <stdio.h>
+ #include <EXTERN.h>
+ #include <perl.h>
+
+ static PerlInterpreter *my_perl;
+
+ int eval(char *string)
+ {
+ char *argv[2];
+ argv[0] = string;
+ argv[1] = NULL;
+ perl_call_argv("_eval_", 0, argv);
+ }
+
+ /** match(string, pattern)
+ **
+ ** Used for matches in a scalar context.
+ **
+ ** Returns 1 if the match was successful; 0 otherwise.
+ **/
+ char match(char *string, char *pattern)
+ {
+ char *command;
+ command = malloc(sizeof(char) * strlen(string) + strlen(pattern) + 37);
+ sprintf(command, "$string = '%s'; $return = $string =~ %s",
+ string, pattern);
+ perl_eval(command);
+ free(command);
+ return SvIV(perl_get_sv("return", FALSE));
+ }
+
+ /** substitute(string, pattern)
+ **
+ ** Used for =~ operations that modify their left-hand side (s/// and tr///)
+ **
+ ** Returns the number of successful matches, and
+ ** modifies the input string if there were any.
+ **/
+ int substitute(char *string[], char *pattern)
+ {
+ char *command;
+ STRLEN length;
+ command = malloc(sizeof(char) * strlen(*string) + strlen(pattern) + 35);
+ sprintf(command, "$string = '%s'; $ret = ($string =~ %s)",
+ *string, pattern);
+ perl_eval(command);
+ free(command);
+ *string = SvPV(perl_get_sv("string", FALSE), length);
+ return SvIV(perl_get_sv("ret", FALSE));
+ }
+
+ /** matches(string, pattern, matches)
+ **
+ ** Used for matches in an array context.
+ **
+ ** Returns the number of matches,
+ ** and fills in **matches with the matching substrings (allocates memory!)
+ **/
+ int matches(char *string, char *pattern, char **matches[])
+ {
+ char *command;
+ SV *current_match;
+ AV *array;
+ I32 num_matches;
+ STRLEN length;
+ int i;
+
+ command = malloc(sizeof(char) * strlen(string) + strlen(pattern) + 38);
+ sprintf(command, "$string = '%s'; @array = ($string =~ %s)",
+ string, pattern);
+ perl_eval(command);
+ free(command);
+ array = perl_get_av("array", FALSE);
+ num_matches = av_len(array) + 1; /** assume $[ is 0 **/
+ *matches = (char **) malloc(sizeof(char *) * num_matches);
+ for (i = 0; i <= num_matches; i++) {
+ current_match = av_shift(array);
+ (*matches)[i] = SvPV(current_match, length);
+ }
+ return num_matches;
+ }
+
+ main (int argc, char **argv, char **env)
+ {
+ char *embedding[] = { "", "-e", "sub _eval_ { eval $_[0] }" };
+ char *text, **matches;
+ int num_matches, i;
+ int j;
+
+ my_perl = perl_alloc();
+ perl_construct( my_perl );
+
+ perl_parse(my_perl, NULL, 3, embedding, env);
+
+ text = (char *) malloc(sizeof(char) * 486); /** A long string follows! **/
+ sprintf(text, "%s", "When he is at a convenience store and the bill comes to some amount like 76 cents, Maynard is aware that there is something he *should* do, something that will enable him to get back a quarter, but he has no idea *what*. He fumbles through his red squeezey changepurse and gives the boy three extra pennies with his dollar, hoping that he might luck into the correct amount. The boy gives him back two of his own pennies and then the big shiny quarter that is his prize. -RICHH");
+
+ if (perl_match(text, "m/quarter/")) /** Does text contain 'quarter'? **/
+ printf("perl_match: Text contains the word 'quarter'.\n\n");
+ else
+ printf("perl_match: Text doesn't contain the word 'quarter'.\n\n");
+
+ if (perl_match(text, "m/eighth/")) /** Does text contain 'eighth'? **/
+ printf("perl_match: Text contains the word 'eighth'.\n\n");
+ else
+ printf("perl_match: Text doesn't contain the word 'eighth'.\n\n");
+
+ /** Match all occurrences of /wi../ **/
+ num_matches = perl_matches(text, "m/(wi..)/g", &matches);
+
+ printf("perl_matches: m/(wi..)/g found %d matches...\n", num_matches);
+ for (i = 0; i < num_matches; i++)
+ printf("match: %s\n", matches[i]);
+ printf("\n");
+ for (i = 0; i < num_matches; i++) {
+ free(matches[i]);
+ }
+ free(matches);
+
+ /** Remove all vowels from text **/
+ num_matches = perl_substitute(&text, "s/[aeiou]//gi");
+ if (num_matches) {
+ printf("perl_substitute: s/[aeiou]//gi...%d substitutions made.\n",
+ num_matches);
+ printf("Now text is: %s\n\n", text);
+ }
+
+ /** Attempt a substitution
+ if (!perl_substitute(&text, "s/Perl/C/")) {
+ printf("perl_substitute: s/Perl/C...No substitution made.\n\n");
+ }
+
+ free(text);
+
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ }
+
+which produces the output
+
+ perl_match: Text contains the word 'quarter'.
+
+ perl_match: Text doesn't contain the word 'eighth'.
+
+ perl_matches: m/(wi..)/g found 2 matches...
+ match: will
+ match: with
+
+ perl_substitute: s/[aeiou]//gi...139 substitutions made.
+ Now text is: Whn h s t cnvnnc str nd th bll cms t sm mnt lk 76 cnts, Mynrd s wr tht thr s smthng h *shld* d, smthng tht wll nbl hm t gt bck qrtr, bt h hs n d *wht*. H fmbls thrgh hs rd sqzy chngprs nd gvs th by thr xtr pnns wth hs dllr, hpng tht h mght lck nt th crrct mnt. Th by gvs hm bck tw f hs wn pnns nd thn th bg shny qrtr tht s hs prz. -RCHH
+
+ perl_substitute: s/Perl/C...No substitution made.
+
+=head2 Fiddling with the Perl stack from your C program
+
+When trying to explain stacks, most computer science textbooks mumble
+something about spring-loaded columns of cafeteria plates: the last
+thing you pushed on the stack is the first thing you pop off. That'll
+do for our purposes: your C program will push some arguments onto "the Perl
+stack", shut its eyes while some magic happens, and then pop the
+results--the return value of your Perl subroutine--off the stack.
+
+First you'll need to know how to convert between C types and Perl
+types, with newSViv() and sv_setnv() and newAV() and all their
+friends. They're described in L<perlguts>.
+
+Then you'll need to know how to manipulate the Perl stack. That's
+described in L<perlcall>.
+
+Once you've understood those, embedding Perl in C is easy.
+
+Since C has no built-in function for integer exponentiation, let's
+make Perl's ** operator available to it (this is less useful than it
+sounds, since Perl implements ** with C's I<pow()> function). First
+I'll create a stub exponentiation function in I<power.pl>:
+
+ sub expo {
+ my ($a, $b) = @_;
+ return $a ** $b;
+ }
+
+Now I'll create a C program, I<power.c>, with a function
+I<PerlPower()> that contains all the perlguts necessary to push the
+two arguments into I<expo()> and to pop the return value out. Take a
+deep breath...
+
+ #include <stdio.h>
+ #include <EXTERN.h>
+ #include <perl.h>
+
+ static PerlInterpreter *my_perl;
+
+ static void
+ PerlPower(int a, int b)
+ {
+ dSP; /* initialize stack pointer */
+ ENTER; /* everything created after here */
+ SAVETMPS; /* ...is a temporary variable. */
+ PUSHMARK(sp); /* remember the stack pointer */
+ XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */
+ XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */
+ PUTBACK; /* make local stack pointer global */
+ perl_call_pv("expo", G_SCALAR); /* call the function */
+ SPAGAIN; /* refresh stack pointer */
+ /* pop the return value from stack */
+ printf ("%d to the %dth power is %d.\n", a, b, POPi);
+ PUTBACK;
+ FREETMPS; /* free that return value */
+ LEAVE; /* ...and the XPUSHed "mortal" args.*/
+ }
+
+ int main (int argc, char **argv, char **env)
+ {
+ char *my_argv[2];
+
+ my_perl = perl_alloc();
+ perl_construct( my_perl );
+
+ my_argv[1] = (char *) malloc(10);
+ sprintf(my_argv[1], "power.pl");
+
+ perl_parse(my_perl, NULL, argc, my_argv, env);
+
+ PerlPower(3, 4); /*** Compute 3 ** 4 ***/
+
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ }
+
+
+
+Compile and run:
+
+ % cc -o power power.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE
+ -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+
+ % power
+ 3 to the 4th power is 81.
+
+=head1 MORAL
+
+You can sometimes I<write faster code> in C, but
+you can always I<write code faster> in Perl. Since you can use
+each from the other, combine them as you wish.
+
+
+=head1 AUTHOR
+
+Jon Orwant F<E<lt>orwant@media.mit.eduE<gt>>, with contributions from
+Tim Bunce, Tom Christiansen, Dov Grobgeld, and Ilya Zakharevich.
+
+December 18, 1995
+
+Some of this material is excerpted from my book: I<Perl 5 Interactive>,
+Waite Group Press, 1996 (ISBN 1-57169-064-6) and appears
+courtesy of Waite Group Press.
+
Lexical variables (declared with "my") are not visible within a
format unless the format is declared within the scope of the lexical
-variable. (They weren't visible at all before version 5.001.) See
+variable. (They weren't visible at all before version 5.001.) Furthermore,
+lexical aliases will not be compiled correctly: see
L<perlfunc/my> for other issues.
Remember the following rule:
-=over 5
+=over 8
-=item *
+=item
I<THERE IS NO GENERAL RULE FOR CONVERTING A LIST INTO A SCALAR!>
operations. In general, they do what you want, unless you want
consistency.
+=head2 Perl Functions by Category
+
+Here are Perl's functions (including things that look like
+functions, like some of the keywords and named operators)
+arranged by category. Some functions appear in more
+than one place.
+
+=over
+
+=item Functions for SCALARs or strings
+
+chomp, chop, chr, crypt, hex, index, lc, lcfirst, length,
+oct, ord, pack, q/STRING/, qq/STRING/, reverse, rindex,
+sprintf, substr, tr///, uc, ucfirst, y///
+
+=item Regular expressions and pattern matching
+
+m//, pos, quotemeta, s///, split, study
+
+=item Numeric functions
+
+abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt,
+srand
+
+=item Functions for real @ARRAYs
+
+pop, push, shift, splice, unshift
+
+=item Functions for list data
+
+grep, join, map, qw/STRING/, reverse, sort, unpack
+
+=item Functions for real %HASHes
+
+delete, each, exists, keys, values
+
+=item Input and output functions
+
+binmode, close, closedir, dbmclose, dbmopen, die, eof,
+fileno, flock, format, getc, print, printf, read, readdir,
+rewinddir, seek, seekdir, select, syscall, sysread,
+syswrite, tell, telldir, truncate, warn, write
+
+=item Functions for fixed length data or records
+
+pack, read, syscall, sysread, syswrite, unpack, vec
+
+=item Functions for filehandles, files, or directories
+
+-X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link,
+lstat, mkdir, open, opendir, readlink, rename, rmdir,
+stat, symlink, umask, unlink, utime
+
+=item Keywords related to the control flow of your perl program
+
+caller, continue, die, do, dump, eval, exit, goto, last,
+next, redo, return, sub, wantarray
+
+=item Keywords related to scoping
+
+caller, import, local, my, package, use
+
+=item Miscellaneous functions
+
+defined, dump, eval, formline, local, my, reset, scalar,
+undef, wantarray
+
+=item Functions for processes and process groups
+
+alarm, exec, fork, getpgrp, getppid, getpriority, kill,
+pipe, qx/STRING/, setpgrp, setpriority, sleep, system,
+times, wait, waitpid
+
+=item Keywords related to perl modules
+
+do, import, no, package, require, use
+
+=item Keywords related to classes and object-orientedness
+
+bless, dbmclose, dbmopen, package, ref, tie, untie, use
+
+=item Low-level socket functions
+
+accept, bind, connect, getpeername, getsockname,
+getsockopt, listen, recv, send, setsockopt, shutdown,
+socket, socketpair
+
+=item System V interprocess communication functions
+
+msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop,
+shmctl, shmget, shmread, shmwrite
+
+=item Fetching user and group info
+
+endgrent, endhostent, endnetent, endpwent, getgrent,
+getgrgid, getgrnam, getlogin, getpwent, getpwnam,
+getpwuid, setgrent, setpwent
+
+=item Fetching network info
+
+endprotoent, endservent, gethostbyaddr, gethostbyname,
+gethostent, getnetbyaddr, getnetbyname, getnetent,
+getprotobyname, getprotobynumber, getprotoent,
+getservbyname, getservbyport, getservent, sethostent,
+setnetent, setprotoent, setservent
+
+=item Time-related functions
+
+gmtime, localtime, time, times
+
+=back
+
+=head2 Alphabetical Listing of Perl Functions
+
+
=over 8
=item -X FILEHANDLE
=item binmode FILEHANDLE
-Arranges for the file to be read or written in "binary" mode in
-operating systems that distinguish between binary and text files.
-Files that are not in binary mode have CR LF sequences translated to LF
-on input and LF translated to CR LF on output. Binmode has no effect
-under Unix; in DOS, it may be imperative--otherwise your DOS C library
-may mangle your file. If FILEHANDLE is an expression,
-the value is taken as the name of the filehandle.
+Arranges for the file to be read or written in "binary" mode in operating
+systems that distinguish between binary and text files. Files that are
+not in binary mode have CR LF sequences translated to LF on input and LF
+translated to CR LF on output. Binmode has no effect under Unix; in DOS
+and similarly archaic systems, it may be imperative--otherwise your
+DOS-damaged C library may mangle your file. The key distinction between
+systems that need binmode and those that don't is their text file
+formats. Systems like Unix and Plan9 that delimit lines with a single
+character, and that encode that character in C as '\n', do not need
+C<binmode>. The rest need it. If FILEHANDLE is an expression, the value
+is taken as the name of the filehandle.
=item bless REF,CLASSNAME
packed address of the appropriate type for the socket. See the examples in
L<perlipc/"Sockets: Client/Server Communication">.
+=item continue BLOCK
+
+Actually a flow control statement rather than a function. If there is a
+C<continue> BLOCK attached to a BLOCK (typically in a C<while> or
+C<foreach>), it is always executed just before the conditional is about to
+be evaluated again, just like the third part of a C<for> loop in C. Thus
+it can be used to increment a loop variable, even when the loop has been
+continued via the C<next> statement (which is similar to the C C<continue>
+statement).
+
=item cos EXPR
Returns the cosine of EXPR (expressed in radians). If EXPR is omitted
[This function has been superseded by the tie() function.]
-This binds a dbm(3), ndbm(3), sdbm(3), gdbm(), or Berkeley DB file to an associative array. ASSOC is the
-name of the associative array. (Unlike normal open, the first argument
-is I<NOT> a filehandle, even though it looks like one). DBNAME is the
-name of the database (without the F<.dir> or F<.pag> extension if any). If the
-database does not exist, it is created with protection specified by
-MODE (as modified by the umask()). If your system only supports the
-older DBM functions, you may perform only one dbmopen() in your program.
-In order versions of Perl,
-if your system had neither DBM nor ndbm, calling dbmopen() produced a
-fatal error; it now falls back to sdbm(3).
+This binds a dbm(3), ndbm(3), sdbm(3), gdbm(), or Berkeley DB file to an
+associative array. ASSOC is the name of the associative array. (Unlike
+normal open, the first argument is I<NOT> a filehandle, even though it
+looks like one). DBNAME is the name of the database (without the F<.dir>
+or F<.pag> extension if any). If the database does not exist, it is
+created with protection specified by MODE (as modified by the umask()).
+If your system only supports the older DBM functions, you may perform only
+one dbmopen() in your program. In older versions of Perl, if your system
+had neither DBM nor ndbm, calling dbmopen() produced a fatal error; it now
+falls back to sdbm(3).
If you don't have write access to the DBM file, you can only read
associative array variables, not set them. If you want to test whether
}
dbmclose(%HIST);
-See also L<DB_File> for many other interesting possibilities.
+See also L<AnyDBM_File> for a more general description of the pros and
+cons of the various dbm apparoches, as well as L<DB_File> for a particularly
+rich implementation.
=item defined EXPR
-Returns a boolean value saying whether the lvalue EXPR has a real value
+Returns a boolean value saying whether EXPR has a real value
or not. Many operations return the undefined value under exceptional
conditions, such as end of file, uninitialized variable, system error
and such. This function allows you to distinguish between an undefined
likewise behave in the same way: they run the code <$x>, which does
nothing at all. (Case 4 is preferred for purely visual reasons.) Case 5
is a place where normally you I<WOULD> like to use double quotes, except
-in that particular situation, you can just use symbolic references
+that in that particular situation, you can just use symbolic references
instead, as in case 6.
=item exec LIST
Calls flock(2) on FILEHANDLE. See L<flock(2)> for definition of
OPERATION. Returns TRUE for success, FALSE on failure. Will produce a
fatal error if used on a machine that doesn't implement either flock(2) or
-fcntl(2). (fcntl(2) will be automatically used if flock(2) is missing.)
+fcntl(2). The fcntl(2) system call will be automatically used if flock(2)
+is missing from your system. This makes flock() the portable file locking
+strategy, although it will only lock entire files, not records. Note also
+that some versions of flock() cannot lock things over the network; you
+would need to use the more system-specific fcntl() for that.
Here's a mailbox appender for BSD systems.
print MBOX $msg,"\n\n";
unlock();
-Note that many versions of flock() cannot lock things over the network.
-You need to do locking with fcntl() for that.
+See also L<DB_File> for other flock() examples.
=item fork
}
waitpid($pid,0);
+See also L<perlipc> for more examples of forking and reaping
+moribund children.
+
+=item format
+
+Declare a picture format with use by the write() function. For
+example:
+
+ format Something =
+ Test: @<<<<<<<< @||||| @>>>>>
+ $str, $%, '$' . int($num)
+ .
+
+ $str = "widget";
+ $num = $cost/$quantiy;
+ $~ = 'Something';
+ write;
+
+See L<perlform> for many details and examples.
+
=item formline PICTURE, LIST
Returns the next character from the input file attached to FILEHANDLE,
or a null string at end of file. If FILEHANDLE is omitted, reads from STDIN.
This is not particularly efficient. It cannot be used to get unbuffered
-single-character
+single-characters, however. For that, try something more like:
if ($BSD_STYLE) {
system "stty cbreak </dev/tty >/dev/tty 2>&1";
}
else {
- system "stty", '-icanon',
- system "stty", 'eol', "\001";
+ system "stty", '-icanon', 'eol', "\001";
}
$key = getc(STDIN);
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
}
else {
- system "stty", 'icanon';
- system "stty", 'eol', '^@'; # ascii null
+ system "stty", 'icanon', 'eol', '^@'; # ascii null
}
print "\n";
Determination of whether to whether $BSD_STYLE should be set
-is left as an exercise to the reader.
+is left as an exercise to the reader.
+
+See also the C<Term::ReadKey> module from your nearest CPAN site;
+details on CPAN can be found on L<perlmod/CPAN>
=item getlogin
}
To sort an array by value, you'll need to use a C<sort{}>
-function. Here's a descending numeric sort by value:
+function. Here's a descending numeric sort of a hash by its values:
foreach $key (sort { $hash{$b} <=> $hash{$a} } keys %hash)) {
printf "%4d %s\n", $hash{$key}, $key;
=item local EXPR
-In general, you should be using "my" instead of "local", because it's
-faster and safer. Format variables often use "local" though, as
-do other variables whose current value must be visible to called
-subroutines. This is known as dynamic scoping. Lexical scoping is
-done with "my", which works more like C's auto declarations.
-
A local modifies the listed variables to be local to the enclosing block,
-subroutine, eval or "do". If more than one value is listed, the list
-must be placed in parens. All the listed elements must be legal
-lvalues. This operator works by saving the current values of those
-variables in LIST on a hidden stack and restoring them upon exiting the
-block, subroutine or eval. This means that called subroutines can also
-reference the local variable, but not the global one. The LIST may be
-assigned to if desired, which allows you to initialize your local
-variables. (If no initializer is given for a particular variable, it
-is created with an undefined value.) Commonly this is used to name the
-parameters to a subroutine. Examples:
-
- sub RANGEVAL {
- local($min, $max, $thunk) = @_;
- local $result = '';
- local $i;
-
- # Presumably $thunk makes reference to $i
-
- for ($i = $min; $i < $max; $i++) {
- $result .= eval $thunk;
- }
-
- $result;
- }
-
-
- if ($sw eq '-v') {
- # init local array with global array
- local @ARGV = @ARGV;
- unshift(@ARGV,'echo');
- system @ARGV;
- }
- # @ARGV restored
+subroutine, C<eval{}> or C<do>. If more than one value is listed, the
+list must be placed in parens. See L<perlsub/"Temporary Values via
+local()"> for details.
-
- # temporarily add to digits associative array
- if ($base12) {
- # (NOTE: not claiming this is efficient!)
- local(%digits) = (%digits,'t',10,'e',11);
- parse_num();
- }
-
-Note that local() is a run-time command, and so gets executed every
-time through a loop. In Perl 4 it used more stack storage each
-time until the loop was exited. Perl 5 reclaims the space each time
-through, but it's still more efficient to declare your variables
-outside the loop.
-
-A local is simply a modifier on an lvalue expression.
-When you assign to a localized EXPR, the local doesn't change whether
-EXPR is viewed as a scalar or an array. So
-
- local($foo) = <STDIN>;
- local @FOO = <STDIN>;
-
-both supply a list context to the righthand side, while
-
- local $foo = <STDIN>;
-
-supplies a scalar context.
+But you really probably want to be using my() instead, because local() isn't
+what most people think of as "local"). See L<perlsub/"Private Variables
+via my()"> for details.
=item localtime EXPR
=item my EXPR
A "my" declares the listed variables to be local (lexically) to the
-enclosing block, subroutine, C<eval>, or C<do/require/use>'d file. If more than one value is
-listed, the list must be placed in parens. All the listed elements
-must be legal lvalues. Only alphanumeric identifiers may be lexically
-scoped--magical builtins like $/ must be localized with "local"
-instead. You also cannot use my() on a package variable.
-In particular, you're not allowed to say
-
- my $_; # Illegal!
- my $pack::$var; # Illegal!
-
-Unlike the "local" declaration, variables declared with "my"
-are totally hidden from the outside world, including any called
-subroutines (even if it's the same subroutine--every call gets its own
-copy).
-
-(An eval(), however, can see the lexical variables of the scope it is
-being evaluated in so long as the names aren't hidden by declarations within
-the eval() itself. See L<perlref>.)
-
-The EXPR may be assigned to if desired, which allows you to initialize
-your variables. (If no initializer is given for a particular
-variable, it is created with an undefined value.) Commonly this is
-used to name the parameters to a subroutine. Examples:
-
- sub RANGEVAL {
- my($min, $max, $thunk) = @_;
- my $result = '';
- my $i;
-
- # Presumably $thunk makes reference to $i
-
- for ($i = $min; $i < $max; $i++) {
- $result .= eval $thunk;
- }
-
- $result;
- }
-
-
- if ($sw eq '-v') {
- # init my array with global array
- my @ARGV = @ARGV;
- unshift(@ARGV,'echo');
- system @ARGV;
- }
- # Outer @ARGV again visible
-
-The "my" is simply a modifier on something you might assign to.
-So when you do assign to the EXPR, the "my" doesn't change whether
-EXPR is viewed as a scalar or an array. So
-
- my ($foo) = <STDIN>;
- my @FOO = <STDIN>;
-
-both supply a list context to the righthand side, while
-
- my $foo = <STDIN>;
-
-supplies a scalar context. But the following only declares one variable:
-
- my $foo, $bar = 1;
-
-That has the same effect as
-
- my $foo;
- $bar = 1;
-
-The declared variable is not introduced (is not visible) until after
-the current statement. Thus,
-
- my $x = $x;
-
-can be used to initialize the new $x with the value of the old $x, and
-the expression
-
- my $x = 123 and $x == 123
-
-is false unless the old $x happened to have the value 123.
-
-Some users may wish to encourage the use of lexically scoped variables.
-As an aid to catching implicit references to package variables,
-if you say
-
- use strict 'vars';
-
-then any variable reference from there to the end of the enclosing
-block must either refer to a lexical variable, or must be fully
-qualified with the package name. A compilation error results
-otherwise. An inner block may countermand this with S<"no strict 'vars'">.
-
-Variables declared with "my" are not part of any package and
-are therefore never fully qualified with the package name.
-However, you may declare a "my" variable at the outer most
-scope of a file to totally hide any such identifiers from the
-outside world. This is similar to a C's static variables
-at the file level. To do this with a subroutine requires the
-use of a closure (anonymous function):
-
- my $secret_version = '1.001-beta';
- my $secret_sub = { print $secret_version };
- &$secret_sub();
-
-This does not work with object methods, however;
-all object methods have to be in the symbol table of some
-package to be found.
-
-Just because the "my" variable is lexically scoped doesn't mean that
-within a function it works like a C static. Here's a mechanism for giving
-a function private variables with both lexical scoping and a static
-lifetime.
-
- #!/usr/bin/perl -l
- $var = "global";
- { my $count = 0;
- my $var = "static";
- sub foo {
- $count++;
- print "$var (call # $count)";
- }
- }
- print $var; foo();
- print $var; foo();
- print $var; foo();
+enclosing block, subroutine, C<eval>, or C<do/require/use>'d file. If
+more than one value is listed, the list must be placed in parens. See
+L<perlsub/"Private Variables via my()"> for details.
=item next LABEL
the same name as the FILEHANDLE contains the filename. If the filename
begins with "<" or nothing, the file is opened for input. If the filename
begins with ">", the file is opened for output. If the filename begins
-with ">>", the file is opened for appending. (You can put a '+' in front
+with ">>", the file is opened for appending. You can put a '+' in front
of the '>' or '<' to indicate that you want both read and write access to
-the file.) If the filename begins with "|", the filename is interpreted
+the file; thus '+<' is usually preferred for read/write updates--the '+>'
+mode would clobber the file first. These correspond to the fopen(3) modes
+of 'r', 'r+', 'w', 'w+', 'a', and 'a+'.
+
+If the filename begins with "|", the filename is interpreted
as a command to which output is to be piped, and if the filename ends with
a "|", the filename is interpreted See L<perlipc/"Using open() for IPC">
for more examples of this. as command which pipes input to us. (You may
-not have a command that pipes both in and out, but see See L<open2>,
+not have a raw open() to a command that pipes both in I<and> out, but see See L<open2>,
L<open3>, and L<perlipc/"Bidirectional Communication"> for alternatives.)
+
Opening '-' opens STDIN and opening '>-' opens STDOUT. Open returns
non-zero upon success, the undefined value otherwise. If the open
involved a pipe, the return value happens to be the pid of the
-subprocess. Examples:
+subprocess.
+
+If you're unfortunate enough to be running Perl on a system that
+distinguishes between text files and binary files (modern operating
+systems don't care), then you should check out L</binmode> for tips for
+dealing with this. The key distinction between systems that need binmode
+and those that don't is their text file formats. Systems like Unix and
+Plan9 that delimit lines with a single character, and that encode that
+character in C as '\n', do not need C<binmode>. The rest need it.
+
+
+Examples:
$ARTICLE = 100;
open ARTICLE or die "Can't find article $ARTICLE: $!\n";
open(LOG, '>>/usr/spool/news/twitlog'); # (log is reserved)
+ open(DBASE, '+<dbase.mine'); # open for update
+
open(ARTICLE, "caesar <$article |"); # decrypt article
open(EXTRACT, "|sort >/tmp/Tmp$$"); # $$ is our process id
name of a filehandle (or file descriptor, if numeric) which is to be
duped and opened. You may use & after >, >>, <, +>, +>> and +<. The
mode you specify should match the mode of the original filehandle.
+(Duping a filehandle does not take into acount any existing contents of
+stdio buffers.)
Here is a script that saves, redirects, and restores STDOUT and
STDERR:
characters in it, it's necessary to protect any leading and trailing
whitespace thusly:
- $file =~ s#^(\s)#./$1#;
- open(FOO, "< $file\0");
+ $file =~ s#^(\s)#./$1#;
+ open(FOO, "< $file\0");
+
+If you want a "real" C open() (see L<open(2)) on your system, then
+you should probably use the POSIX::open() function as found in the L<POSIX>
+documents. For example:
+
+ use FileHandle;
+ use POSIX qw(:fcntl_h);
+ $fd = POSIX::open($path, O_RDWR|O_CREAT|O_EXCL, 0700);
+ die "POSIX::open $path: $!" unless defined $fd;
+ $fh = FileHandle->new_from_fd($fd, $amode) || die "fdopen: $!";
+ $fh->autoflush(1);
+ $fh->print("stuff $$\n");
+ seek($fh, 0, SEEK_SET);
+ print "File contains: ", <$fh>;
+
+See L</seek()> for some details about mixing reading and writing.
=item opendir DIRHANDLE,EXPR
The same template may generally also be used in the unpack function.
+=item package NAMESPACE
+
+Declares the compilation unit as being in the given namespace. The scope
+of the package declaration is from the declaration itself through the end of
+the enclosing block (the same scope as the local() operator). All further
+unqualified dynamic identifiers will be in this namespace. A package
+statement only affects dynamic variables--including those you've used
+local() on--but I<not> lexical variables created with my(). Typically it
+would be the first declaration in a file to be included by the C<require>
+or C<use> operator. You can switch into a package in more than one place;
+it merely influences which symbol table is used by the compiler for the
+rest of that block. You can refer to variables and filehandles in other
+packages by prefixing the identifier with the package name and a double
+colon: C<$Package::Variable>. If the package name is null, the C<main>
+package as assumed. That is, C<$::sail> is equivalent to C<$main::sail>.
+
+See L<perlmod/"Packages"> for more information about packages, modules,
+and classes. See L<perlsub> for other scoping issues.
+
=item pipe READHANDLE,WRITEHANDLE
Opens a pair of connected pipes like the corresponding system call.
$tmp = $ARRAY[$#ARRAY--];
If there are no elements in the array, returns the undefined value.
+If ARRAY is omitted, pops the
+@ARGV array in the main program, and the @_ array in subroutines, just
+like shift().
=item pos SCALAR
=item print
-Prints a string or a comma-separated list of strings. Returns non-zero
+Prints a string or a comma-separated list of strings. Returns TRUE
if successful. FILEHANDLE may be a scalar variable name, in which case
-the variable contains the name of the filehandle, thus introducing one
+the variable contains the name of or a reference to the filehandle, thus introducing one
level of indirection. (NOTE: If FILEHANDLE is a variable and the next
token is a term, it may be misinterpreted as an operator unless you
interpose a + or put parens around the arguments.) If FILEHANDLE is
directory. If there are no more entries, returns an undefined value in
a scalar context or a null list in a list context.
+If you're planning to filetest the return values out of a readdir(), you'd
+better prepend the directory in question. Otherwise, since we didn't
+chdir() there, it would have been testing the wrong file.
+
+ opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
+ @dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR);
+ closedir DIR;
+
=item readlink EXPR
Returns the value of a symbolic link, if symbolic links are
=item scalar EXPR
Forces EXPR to be interpreted in a scalar context and returns the value
-of EXPR.
+of EXPR.
+
+ @counts = ( scalar @a, scalar @b, scalar @c );
+
+There is no equivalent operator to force an expression to
+be interpolated in a list context because it's in practice never
+needed. If you really wanted to do so, however, you could use
+the construction C<@{[ (some expression) ]}>, but usually a simple
+C<(some expression)> suffices.
=item seek FILEHANDLE,POSITION,WHENCE
plus offset. You may use the values SEEK_SET, SEEK_CUR, and SEEK_END for
this from POSIX module. Returns 1 upon success, 0 otherwise.
+On some systems you have to do a seek whenever you switch between reading
+and writing. Amongst other things, this may have the effect of calling
+stdio's clearerr(3). A "whence" of 1 (SEEK_CUR) is useful for not moving
+the file pointer:
+
+ seek(TEST,0,1);
+
+This is also useful for applications emulating C<tail -f>. Once you hit
+EOF on your read, and then sleep for a while, you might have to stick in a
+seek() to reset things. First the simple trick listed above to clear the
+filepointer. The seek() doesn't change the current position, but it
+I<does> clear the end-of-file condition on the handle, so that the next
+C<E<lt>FILE<E<gt>> makes Perl try again to read something. Hopefully.
+
+If that doesn't work (some stdios are particularly cantankerous), then
+you may need something more like this:
+
+ for (;;) {
+ for ($curpos = tell(FILE); $_ = <FILE>; $curpos = tell(FILE)) {
+ # search for some stuff and put it into files
+ }
+ sleep($for_a_while);
+ seek(FILE, $curpos, 0);
+ }
+
=item seekdir DIRHANDLE,POS
Sets the current position for the readdir() routine on DIRHANDLE. POS
select(undef, undef, undef, 0.25);
+B<WARNING>: Do not attempt to mix buffered I/O (like read() or <FH>)
+with select(). You have to use sysread() instead.
=item semctl ID,SEMNUM,CMD,ARG
you requested, depending on how it counts seconds. Most modern systems
always sleep the full amount.
+For delays of finer granularity than one second, you may use Perl's
+syscall() interface to access setitimer(2) if your system supports it,
+or else see L</select()> below.
+
=item socket SOCKET,DOMAIN,TYPE,PROTOCOL
Opens a socket of the specified kind and attaches it to filehandle
SUBNAME, you can provide a BLOCK as an anonymous, in-line sort
subroutine.
-In the interests of efficiency the normal calling code for subroutines
-is bypassed, with the following effects: the subroutine may not be a
-recursive subroutine, and the two elements to be compared are passed
-into the subroutine not via @_ but as $a and $b (see example below).
-They are passed by reference, so don't modify $a and $b.
+In the interests of efficiency the normal calling code for subroutines is
+bypassed, with the following effects: the subroutine may not be a
+recursive subroutine, and the two elements to be compared are passed into
+the subroutine not via @_ but as the package global variables $a and
+$b (see example below). They are passed by reference, so don't
+modify $a and $b. And don't try to declare them as lexicals either.
Examples:
# same thing, but with explicit sort routine
@articles = sort {$a cmp $b} @files;
+ # now case-insensitively
+ @articles = sort { uc($a) cmp uc($b)} @files;
+
# same thing in reversed order
@articles = sort {$b cmp $a} @files;
print sort @george, 'to', @harry;
# prints AbelAxedCainPunishedcatchaseddoggonetoxyz
+ # inefficiently sort by descending numeric compare using
+ # the first integer after the first = sign, or the
+ # whole record case-insensitively otherwise
+
+ @new = sort {
+ ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
+ ||
+ uc($a) cmp uc($b)
+ } @old;
+
+ # same thing, but much more efficiently;
+ # we'll build auxiliary indices instead
+ # for speed
+ @nums = @caps = ();
+ for (@old) {
+ push @nums, /=(\d+)/;
+ push @caps, uc($_);
+ }
+
+ @new = @old[ sort {
+ $nums[$b] <=> $nums[$a]
+ ||
+ $caps[$a] cmp $caps[$b]
+ } 0..$#old
+ ];
+
+ # same thing using a Schwartzian Transform (no temps)
+ @new = map { $_->[0] }
+ sort { $b->[1] <=> $a->[1]
+ ||
+ $a->[2] cmp $b->[2]
+ } map { [$_, /=(\d+)/, uc($_)] } @old;
+
+If you're and using strict, you I<MUST NOT> declare $a
+and $b as lexicals. They are package globals. That means
+if you're in the C<main> package, it's
+
+ @articles = sort {$main::b <=> $main::a} @files;
+
+or just
+
+ @articles = sort {$::b <=> $::a} @files;
+
+but if you're in the C<FooPack> package, it's
+
+ @articles = sort {$FooPack::b <=> $FooPack::a} @files;
+
=item splice ARRAY,OFFSET,LENGTH,LIST
=item splice ARRAY,OFFSET,LENGTH
=item sprintf FORMAT,LIST
Returns a string formatted by the usual printf conventions of the C
-language. (The * character for an indirectly specified length is not
+language. See L<sprintf(3)> or L<printf(3)> on your system for details.
+(The * character for an indirectly specified length is not
supported, but you can get the same effect by interpolating a variable
-into the pattern.) Some C libraries' implementations of sprintf() can dump core
-when fed ludiocrous arguments.
+into the pattern.) Some C libraries' implementations of sprintf() can
+dump core when fed ludicrous arguments.
=item sqrt EXPR
=item srand EXPR
-Sets the random number seed for the C<rand> operator. If EXPR is
-omitted, does C<srand(time)>. Of course, you'd need something much more
-random than that for cryptographic purposes, since it's easy to guess
-the current time. Checksumming the compressed output of rapidly
-changing operating system status programs is the usual method.
-Examples are posted regularly to comp.security.unix.
+Sets the random number seed for the C<rand> operator. If EXPR is omitted,
+does C<srand(time)>. Many folks use an explicit C<srand(time ^ $$)>
+instead. Of course, you'd need something much more random than that for
+cryptographic purposes, since it's easy to guess the current time.
+Checksumming the compressed output of rapidly changing operating system
+status programs is the usual method. Examples are posted regularly to
+the comp.security.unix newsgroup.
=item stat FILEHANDLE
print $file, "\n";
}
+=item sub BLOCK
+
+=item sub NAME
+
+=item sub NAME BLOCK
+
+This is subroutine definition, not a real function I<per se>. With just a
+NAME (and possibly prototypes), it's just a forward declaration. Without
+a NAME, it's an anonymous function declaration, and does actually return a
+value: the CODE ref of the closure you just created. See L<perlsub> and
+L<perlref> for details.
+
=item substr EXPR,OFFSET,LEN
=item substr EXPR,OFFSET
Note that argument processing varies depending on the number of
arguments. The return value is the exit status of the program as
returned by the wait() call. To get the actual exit value divide by
-256. See also L</exec>.
+256. See also L</exec>. This is I<NOT> what you want to use to capture
+the output from a command, for that you should merely use backticks, as
+described in L<perlop/"`STRING`">.
=item syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET
of correct type. Any additional arguments are passed to the "new"
method of the class (meaning TIESCALAR, TIEARRAY, or TIEHASH).
Typically these are arguments such as might be passed to the dbm_open()
-function of C. The object returned by the "new" method +is also
-returned by the tie() function, which would be useful if you +want to
+function of C. The object returned by the "new" method is also
+returned by the tie() function, which would be useful if you want to
access other methods in CLASSNAME.
Note that functions such as keys() and values() may return huge array
BEGIN { require Module; import Module LIST; }
-If you don't want your namespace altered, use require instead.
-
The BEGIN forces the require and import to happen at compile time. The
require makes sure the module is loaded into memory if it hasn't been
yet. The import is not a builtin--it's just an ordinary static method
features back into the current package. The module can implement its
import method any way it likes, though most modules just choose to
derive their import method via inheritance from the Exporter class that
-is defined in the Exporter module.
+is defined in the Exporter module. See L<Exporter>.
+
+If you don't want your namespace altered, explicitly supply an empty list:
+
+ use Module ();
+
+That is exactly equivalent to
+
+ BEGIN { require Module; }
Because this is a wide-open interface, pragmas (compiler directives)
are also implemented this way. Currently implemented pragmas are:
SV* newSVpv(char*, int);
SV* newSVsv(SV*);
-To change the value of an *already-existing* scalar, there are five routines:
+To change the value of an *already-existing* SV, there are five routines:
void sv_setiv(SV*, IV);
void sv_setnv(SV*, double);
Notice that you can choose to specify the length of the string to be
assigned by using C<sv_setpvn> or C<newSVpv>, or you may allow Perl to
-calculate the length by using C<sv_setpv> or specifying 0 as the second
+calculate the length by using C<sv_setpv> or by specifying 0 as the second
argument to C<newSVpv>. Be warned, though, that Perl will determine the
string's length by using C<strlen>, which depends on the string terminating
with a NUL character.
SvCUR(SV*)
SvCUR_set(SV*, I32 val)
-But note that these are valid only if C<SvPOK()> is true.
+You can also get a pointer to the end of the string stored in the SV
+with the macro:
+
+ SvEND(SV*)
+
+But note that these last three macros are valid only if C<SvPOK()> is true.
If you want to append something to the end of string stored in an C<SV*>,
you can use the following functions:
SV** av_store(AV*, I32 key, SV* val);
/* Stores val at offset key */
-Take note that these two functions return C<SV**>'s, not C<SV*>'s.
+Take note that C<av_fetch> and C<av_store> return C<SV**>'s, not C<SV*>'s.
void av_clear(AV*);
/* Clear out all elements, but leave the array */
void av_undef(AV*);
/* Undefines the array, removing all elements */
+ void av_extend(AV*, I32 key);
+ /* Extend the array to a total of key elements */
If you know the name of an array variable, you can get a pointer to its AV
by using the following:
char* hv_iterkey(HE* entry, I32* retlen);
/* Get the key from an HE structure and also return
the length of the key string */
- SV* hv_iterval(HV*, HE* entry);
+ SV* hv_iterval(HV*, HE* entry);
/* Return a SV pointer to the value of the HE
structure */
- SV* hv_iternextsv(HV*, char** key, I32* retlen);
+ SV* hv_iternextsv(HV*, char** key, I32* retlen);
/* This convenience routine combines hv_iternext,
hv_iterkey, and hv_iterval. The key and retlen
arguments are return values for the key and its
while (i--)
hash = hash * 33 + *s++;
-=head1 Creating New Variables
-
-To create a new Perl variable, which can be accessed from your Perl script,
-use the following routines, depending on the variable type.
-
- SV* perl_get_sv("varname", TRUE);
- AV* perl_get_av("varname", TRUE);
- HV* perl_get_hv("varname", TRUE);
-
-Notice the use of TRUE as the second parameter. The new variable can now
-be set, using the routines appropriate to the data type.
-
-There are additional bits that may be OR'ed with the TRUE argument to enable
-certain extra features. Those bits are:
-
- 0x02 Marks the variable as multiply defined, thus preventing the
- "Indentifier <varname> used only once: possible typo" warning.
- 0x04 Issues a "Had to create <varname> unexpectedly" warning if
- the variable didn't actually exist. This is useful if
- you expected the variable to already exist and want to propagate
- this warning back to the user.
-
-If the C<varname> argument does not contain a package specifier, it is
-created in the current package.
-
=head2 References
References are a special type of scalar that point to other data types
To create a reference, use the following command:
- SV* newRV((SV*) thing);
+ SV* newRV((SV*) thing);
The C<thing> argument can be any of an C<SV*>, C<AV*>, or C<HV*>. Once
you have a reference, you can use the following macro to dereference the
SVt_PVCV Code
SVt_PVMG Blessed Scalar
+=head2 Blessed References and Class Objects
+
+References are also used to support object-oriented programming. In the
+OO lexicon, an object is simply a reference that has been blessed into a
+package (or class). Once blessed, the programmer may now use the reference
+to access the various methods in the class.
+
+A reference can be blessed into a package with the following function:
+
+ SV* sv_bless(SV* sv, HV* stash);
+
+The C<sv> argument must be a reference. The C<stash> argument specifies
+which class the reference will belong to. See the section on L<Stashes>
+for information on converting class names into stashes.
+
+/* Still under construction */
+
+Upgrades rv to reference if not already one. Creates new SV for rv to
+point to.
+If classname is non-null, the SV is blessed into the specified class.
+SV is returned.
+
+ SV* newSVrv(SV* rv, char* classname);
+
+Copies integer or double into an SV whose reference is rv. SV is blessed
+if classname is non-null.
+
+ SV* sv_setref_iv(SV* rv, char* classname, IV iv);
+ SV* sv_setref_nv(SV* rv, char* classname, NV iv);
+
+Copies pointer (I<not a string!>) into an SV whose reference is rv.
+SV is blessed if classname is non-null.
+
+ SV* sv_setref_pv(SV* rv, char* classname, PV iv);
+
+Copies string into an SV whose reference is rv.
+Set length to 0 to let Perl calculate the string length.
+SV is blessed if classname is non-null.
+
+ SV* sv_setref_pvn(SV* rv, char* classname, PV iv, int length);
+
+ int sv_isa(SV* sv, char* name);
+ int sv_isobject(SV* sv);
+
+=head1 Creating New Variables
+
+To create a new Perl variable, which can be accessed from your Perl script,
+use the following routines, depending on the variable type.
+
+ SV* perl_get_sv("varname", TRUE);
+ AV* perl_get_av("varname", TRUE);
+ HV* perl_get_hv("varname", TRUE);
+
+Notice the use of TRUE as the second parameter. The new variable can now
+be set, using the routines appropriate to the data type.
+
+There are additional bits that may be OR'ed with the TRUE argument to enable
+certain extra features. Those bits are:
+
+ 0x02 Marks the variable as multiply defined, thus preventing the
+ "Indentifier <varname> used only once: possible typo" warning.
+ 0x04 Issues a "Had to create <varname> unexpectedly" warning if
+ the variable didn't actually exist. This is useful if
+ you expected the variable to already exist and want to propagate
+ this warning back to the user.
+
+If the C<varname> argument does not contain a package specifier, it is
+created in the current package.
+
=head1 XSUB's and the Argument Stack
The XSUB mechanism is a simple way for Perl programs to access C subroutines.
itself).
Add cruft about reference counts.
+ int SvREFCNT(SV* sv);
+ void SvREFCNT_inc(SV* sv);
+ void SvREFCNT_dec(SV* sv);
In the above example with C<tzname>, we needed to create two new SV's to push
onto the argument stack, that being the two strings. However, we don't want
by passing their address (and casting them to C<SV*>) to the C<sv_2mortal> or
C<sv_mortalcopy> routines.
-From Ilya:
+>From Ilya:
Beware that the sv_2mortal() call is eventually equivalent to
svREFCNT_dec(). A value can happily be mortal in two different contexts,
and it will be svREFCNT_dec()ed twice, once on exit from these
strange things to happen should you make the same value mortal within
multiple contexts.
-=head1 Stashes and Objects
+=head1 Stashes
A stash is a hash table (associative array) that contains all of the
different objects that are contained within a package. Each key of the
that have the same name), and each value in the hash table is called a
GV (for Glob Value). This GV in turn contains references to the various
objects of that name, including (but not limited to) the following:
-
+
Scalar Value
Array Value
Hash Value
The first function takes a literal string, the second uses the string stored
in the SV. Remember that a stash is just a hash table, so you get back an
-C<HV*>.
+C<HV*>. The C<create> flag will create a new package if it is set.
The name that C<gv_stash*v> wants is the name of the package whose symbol table
you want. The default package is called C<main>. If you have multiply nested
The sv_magic function uses C<how> to determine which, if any, predefined
"Magic Virtual Table" should be assigned to the C<mg_virtual> field.
-See the "Magic Virtual Table" section below.
+See the "Magic Virtual Table" section below. The C<how> argument is also
+stored in the C<mg_type> field.
The C<obj> argument is stored in the C<mg_obj> field of the C<MAGIC>
structure. If it is not the same as the C<sv> argument, the reference
the C<how> argument is "#", or if it is a null pointer, then C<obj> is
merely stored, without the reference count being incremented.
+There is also a function to add magic to an C<HV>:
+
+ void hv_magic(HV *hv, GV *gv, int how);
+
+This simply calls C<sv_magic> and coerces the C<gv> argument into an C<SV>.
+
+To remove the magic from an SV, call the function sv_unmagic:
+
+ void sv_unmagic(SV *sv, int type);
+
+The C<type> argument should be equal to the C<how> value when the C<SV>
+was initially made magical.
+
=head2 Magic Virtual Tables
The C<mg_virtual> field in the C<MAGIC> structure is a pointer to a
FREETMPS
LEAVE
XPUSH*()
+ POP*()
For more information, consult L<perlcall>.
instances of the size of the C<type> data structure (using the C<sizeof>
function).
-=head1 AUTHOR
+=head1 API LISTING
-Jeff Okamoto <okamoto@corp.hp.com>
+This is a listing of functions, macros, flags, and variables that may be
+useful to extension writers or that may be found while reading other
+extensions.
-With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
-Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
-Bowers, Matthew Green, Tim Bunce, and Spider Boardman.
+=over 8
-=head1 DATE
+=item AvFILL
+
+See C<av_len>.
+
+=item av_clear
+
+Clears an array, making it empty.
+
+ void av_clear _((AV* ar));
+
+=item av_extend
+
+Pre-extend an array. The C<key> is the index to which the array should be
+extended.
+
+ void av_extend _((AV* ar, I32 key));
+
+=item av_fetch
+
+Returns the SV at the specified index in the array. The C<key> is the
+index. If C<lval> is set then the fetch will be part of a store. Check
+that the return value is non-null before dereferencing it to a C<SV*>.
+
+ SV** av_fetch _((AV* ar, I32 key, I32 lval));
+
+=item av_len
+
+Returns the highest index in the array. Returns -1 if the array is empty.
+
+ I32 av_len _((AV* ar));
+
+=item av_make
+
+Creats a new AV and populates it with a list of SVs. The SVs are copied
+into the array, so they may be freed after the call to av_make.
+
+ AV* av_make _((I32 size, SV** svp));
+
+=item av_pop
+
+Pops an SV off the end of the array. Returns C<&sv_undef> if the array is
+empty.
+
+ SV* av_pop _((AV* ar));
+
+=item av_push
+
+Pushes an SV onto the end of the array.
+
+ void av_push _((AV* ar, SV* val));
+
+=item av_shift
+
+Shifts an SV off the beginning of the array.
+
+ SV* av_shift _((AV* ar));
+
+=item av_store
+
+Stores an SV in an array. The array index is specified as C<key>. The
+return value will be null if the operation failed, otherwise it can be
+dereferenced to get the original C<SV*>.
+
+ SV** av_store _((AV* ar, I32 key, SV* val));
+
+=item av_undef
+
+Undefines the array.
+
+ void av_undef _((AV* ar));
+
+=item av_unshift
+
+Unshift an SV onto the beginning of the array.
+
+ void av_unshift _((AV* ar, I32 num));
+
+=item CLASS
+
+Variable which is setup by C<xsubpp> to indicate the class name for a C++ XS
+constructor. This is always a C<char*>. See C<THIS> and L<perlxs>.
+
+=item Copy
+
+The XSUB-writer's interface to the C C<memcpy> function. The C<s> is the
+source, C<d> is the destination, C<n> is the number of items, and C<t> is
+the type.
+
+ (void) Copy( s, d, n, t );
+
+=item croak
+
+This is the XSUB-writer's interface to Perl's C<die> function. Use this
+function the same way you use the C C<printf> function. See C<warn>.
+
+=item CvSTASH
+
+Returns the stash of the CV.
+
+ HV * CvSTASH( SV* sv )
+
+=item DBsingle
+
+When Perl is run in debugging mode, with the B<-d> switch, this SV is a
+boolean which indicates whether subs are being single-stepped.
+Single-stepping is automatically turned on after every step. See C<DBsub>.
+
+=item DBsub
+
+When Perl is run in debugging mode, with the B<-d> switch, this GV contains
+the SV which holds the name of the sub being debugged. See C<DBsingle>.
+The sub name can be found by
+
+ SvPV( GvSV( DBsub ), na )
+
+=item dMARK
+
+Declare a stack marker for the XSUB. See C<MARK> and C<dORIGMARK>.
+
+=item dORIGMARK
+
+Saves the original stack mark for the XSUB. See C<ORIGMARK>.
+
+=item dSP
+
+Declares a stack pointer for the XSUB. See C<SP>.
+
+=item dXSARGS
+
+Sets up stack and mark pointers for an XSUB, calling dSP and dMARK. This is
+usually handled automatically by C<xsubpp>. Declares the C<items> variable
+to indicate the number of items on the stack.
+
+=item ENTER
+
+Opening bracket on a callback. See C<LEAVE> and L<perlcall>.
+
+ ENTER;
+
+=item EXTEND
+
+Used to extend the argument stack for an XSUB's return values.
+
+ EXTEND( sp, int x );
+
+=item FREETMPS
+
+Closing bracket for temporaries on a callback. See C<SAVETMPS> and
+L<perlcall>.
+
+ FREETMPS;
+
+=item G_ARRAY
+
+Used to indicate array context. See C<GIMME> and L<perlcall>.
+
+=item G_DISCARD
+
+Indicates that arguments returned from a callback should be discarded. See
+L<perlcall>.
+
+=item G_EVAL
+
+Used to force a Perl C<eval> wrapper around a callback. See L<perlcall>.
+
+=item GIMME
+
+The XSUB-writer's equivalent to Perl's C<wantarray>. Returns C<G_SCALAR> or
+C<G_ARRAY> for scalar or array context.
+
+=item G_NOARGS
+
+Indicates that no arguments are being sent to a callback. See L<perlcall>.
+
+=item G_SCALAR
+
+Used to indicate scalar context. See C<GIMME> and L<perlcall>.
+
+=item gv_stashpv
+
+Returns a pointer to the stash for a specified package. If C<create> is set
+then the package will be created if it does not already exist. If C<create>
+is not set and the package does not exist then NULL is returned.
+
+ HV* gv_stashpv _((char* name, I32 create));
+
+=item gv_stashsv
+
+Returns a pointer to the stash for a specified package. See C<gv_stashpv>.
+
+ HV* gv_stashsv _((SV* sv, I32 create));
+
+=item GvSV
+
+Return the SV from the GV.
+
+=item he_free
+
+Releases a hash entry from an iterator. See C<hv_iternext>.
+
+=item hv_clear
+
+Clears a hash, making it empty.
+
+ void hv_clear _((HV* tb));
+
+=item hv_delete
+
+Deletes a key/value pair in the hash. The value SV is removed from the hash
+and returned to the caller. The C<lken> is the length of the key. The
+C<flags> value will normally be zero; if set to G_DISCARD then null will be
+returned.
+
+ SV* hv_delete _((HV* tb, char* key, U32 klen, I32 flags));
+
+=item hv_exists
+
+Returns a boolean indicating whether the specified hash key exists. The
+C<lken> is the length of the key.
+
+ bool hv_exists _((HV* tb, char* key, U32 klen));
+
+=item hv_fetch
+
+Returns the SV which corresponds to the specified key in the hash. The
+C<lken> is the length of the key. If C<lval> is set then the fetch will be
+part of a store. Check that the return value is non-null before
+dereferencing it to a C<SV*>.
+
+ SV** hv_fetch _((HV* tb, char* key, U32 klen, I32 lval));
+
+=item hv_iterinit
+
+Prepares a starting point to traverse a hash table.
+
+ I32 hv_iterinit _((HV* tb));
+
+=item hv_iterkey
+
+Returns the key from the current position of the hash iterator. See
+C<hv_iterinit>.
+
+ char* hv_iterkey _((HE* entry, I32* retlen));
+
+=item hv_iternext
+
+Returns entries from a hash iterator. See C<hv_iterinit>.
+
+ HE* hv_iternext _((HV* tb));
+
+=item hv_iternextsv
+
+Performs an C<hv_iternext>, C<hv_iterkey>, and C<hv_iterval> in one
+operation.
+
+ SV * hv_iternextsv _((HV* hv, char** key, I32* retlen));
+
+=item hv_iterval
+
+Returns the value from the current position of the hash iterator. See
+C<hv_iterkey>.
+
+ SV* hv_iterval _((HV* tb, HE* entry));
+
+=item hv_magic
+
+Adds magic to a hash. See C<sv_magic>.
+
+ void hv_magic _((HV* hv, GV* gv, int how));
+
+=item HvNAME
+
+Returns the package name of a stash. See C<SvSTASH>, C<CvSTASH>.
+
+ char *HvNAME (HV* stash)
+
+=item hv_store
+
+Stores an SV in a hash. The hash key is specified as C<key> and C<klen> is
+the length of the key. The C<hash> parameter is the pre-computed hash
+value; if it is zero then Perl will compute it. The return value will be
+null if the operation failed, otherwise it can be dereferenced to get the
+original C<SV*>.
+
+ SV** hv_store _((HV* tb, char* key, U32 klen, SV* val, U32 hash));
+
+=item hv_undef
+
+Undefines the hash.
+
+ void hv_undef _((HV* tb));
+
+=item isALNUM
+
+Returns a boolean indicating whether the C C<char> is an ascii alphanumeric
+character or digit.
+
+ int isALNUM (char c)
+
+=item isALPHA
+
+Returns a boolean indicating whether the C C<char> is an ascii alphanumeric
+character.
+
+ int isALPHA (char c)
+
+=item isDIGIT
+
+Returns a boolean indicating whether the C C<char> is an ascii digit.
+
+ int isDIGIT (char c)
+
+=item isLOWER
+
+Returns a boolean indicating whether the C C<char> is a lowercase character.
+
+ int isLOWER (char c)
+
+=item isSPACE
+
+Returns a boolean indicating whether the C C<char> is whitespace.
+
+ int isSPACE (char c)
+
+=item isUPPER
+
+Returns a boolean indicating whether the C C<char> is an uppercase character.
+
+ int isUPPER (char c)
+
+=item items
+
+Variable which is setup by C<xsubpp> to indicate the number of items on the
+stack. See L<perlxs>.
+
+=item LEAVE
+
+Closing bracket on a callback. See C<ENTER> and L<perlcall>.
+
+ LEAVE;
+
+=item MARK
+
+Stack marker for the XSUB. See C<dMARK>.
+
+=item mg_clear
+
+Clear something magical that the SV represents. See C<sv_magic>.
+
+ int mg_clear _((SV* sv));
+
+=item mg_copy
+
+Copies the magic from one SV to another. See C<sv_magic>.
+
+ int mg_copy _((SV *, SV *, char *, STRLEN));
+
+=item mg_find
+
+Finds the magic pointer for type matching the SV. See C<sv_magic>.
+
+ MAGIC* mg_find _((SV* sv, int type));
+
+=item mg_free
+
+Free any magic storage used by the SV. See C<sv_magic>.
+
+ int mg_free _((SV* sv));
+
+=item mg_get
+
+Do magic after a value is retrieved from the SV. See C<sv_magic>.
+
+ int mg_get _((SV* sv));
+
+=item mg_len
+
+Report on the SV's length. See C<sv_magic>.
+
+ U32 mg_len _((SV* sv));
+
+=item mg_magical
+
+Turns on the magical status of an SV. See C<sv_magic>.
+
+ void mg_magical _((SV* sv));
+
+=item mg_set
+
+Do magic after a value is assigned to the SV. See C<sv_magic>.
+
+ int mg_set _((SV* sv));
+
+=item Move
+
+The XSUB-writer's interface to the C C<memmove> function. The C<s> is the
+source, C<d> is the destination, C<n> is the number of items, and C<t> is
+the type.
+
+ (void) Move( s, d, n, t );
+
+=item na
+
+A variable which may be used with C<SvPV> to tell Perl to calculate the
+string length.
+
+=item New
+
+The XSUB-writer's interface to the C C<malloc> function.
+
+ void * New( x, void *ptr, int size, type )
+
+=item Newc
+
+The XSUB-writer's interface to the C C<malloc> function, with cast.
+
+ void * Newc( x, void *ptr, int size, type, cast )
+
+=item Newz
+
+The XSUB-writer's interface to the C C<malloc> function. The allocated
+memory is zeroed with C<memzero>.
+
+ void * Newz( x, void *ptr, int size, type )
+
+=item newAV
+
+Creates a new AV. The refcount is set to 1.
+
+ AV* newAV _((void));
+
+=item newHV
+
+Creates a new HV. The refcount is set to 1.
+
+ HV* newHV _((void));
+
+=item newRV
+
+Creates an RV wrapper for an SV. The refcount for the original SV is
+incremented.
+
+ SV* newRV _((SV* ref));
+
+=item newSV
+
+Creates a new SV. The C<len> parameter indicates the number of bytes of
+pre-allocated string space the SV should have. The refcount for the new SV
+is set to 1.
+
+ SV* newSV _((STRLEN len));
+
+=item newSViv
+
+Creates a new SV and copies an integer into it. The refcount for the SV is
+set to 1.
+
+ SV* newSViv _((IV i));
+
+=item newSVnv
+
+Creates a new SV and copies a double into it. The refcount for the SV is
+set to 1.
+
+ SV* newSVnv _((NV i));
+
+=item newSVpv
+
+Creates a new SV and copies a string into it. The refcount for the SV is
+set to 1. If C<len> is zero then Perl will compute the length.
+
+ SV* newSVpv _((char* s, STRLEN len));
+
+=item newSVrv
+
+Creates a new SV for the RV, C<rv>, to point to. If C<rv> is not an RV then
+it will be upgraded one. If C<classname> is non-null then the new SV will
+be blessed in the specified package. The new SV is returned and its
+refcount is 1.
+
+ SV* newSVrv _((SV* rv, char* classname));
+
+=item newSVsv
+
+Creates a new SV which is an exact duplicate of the orignal SV.
+
+ SV* newSVsv _((SV* old));
+
+=item newXS
+
+Used by C<xsubpp> to hook up XSUBs as Perl subs.
+
+=item newXSproto
+
+Used by C<xsubpp> to hook up XSUBs as Perl subs. Adds Perl prototypes to
+the subs.
+
+=item Nullav
+
+Null AV pointer.
+
+=item Nullch
+
+Null character pointer.
+
+=item Nullcv
+
+Null CV pointer.
+
+=item Nullhv
+
+Null HV pointer.
+
+=item Nullsv
+
+Null SV pointer.
+
+=item ORIGMARK
+
+The original stack mark for the XSUB. See C<dORIGMARK>.
+
+=item perl_alloc
+
+Allocates a new Perl interpreter. See L<perlembed>.
+
+=item perl_call_argv
+
+Performs a callback to the specified Perl sub. See L<perlcall>.
+
+ I32 perl_call_argv _((char* subname, I32 flags, char** argv));
+
+=item perl_call_method
+
+Performs a callback to the specified Perl method. The blessed object must
+be on the stack. See L<perlcall>.
+
+ I32 perl_call_method _((char* methname, I32 flags));
+
+=item perl_call_pv
+
+Performs a callback to the specified Perl sub. See L<perlcall>.
+
+ I32 perl_call_pv _((char* subname, I32 flags));
+
+=item perl_call_sv
+
+Performs a callback to the Perl sub whose name is in the SV. See
+L<perlcall>.
+
+ I32 perl_call_sv _((SV* sv, I32 flags));
+
+=item perl_construct
+
+Initializes a new Perl interpreter. See L<perlembed>.
+
+=item perl_destruct
+
+Shuts down a Perl interpreter. See L<perlembed>.
+
+=item perl_eval_sv
+
+Tells Perl to C<eval> the string in the SV.
+
+ I32 perl_eval_sv _((SV* sv, I32 flags));
+
+=item perl_free
+
+Releases a Perl interpreter. See L<perlembed>.
+
+=item perl_get_av
+
+Returns the AV of the specified Perl array. If C<create> is set and the
+Perl variable does not exist then it will be created. If C<create> is not
+set and the variable does not exist then null is returned.
+
+ AV* perl_get_av _((char* name, I32 create));
+
+=item perl_get_cv
+
+Returns the CV of the specified Perl sub. If C<create> is set and the Perl
+variable does not exist then it will be created. If C<create> is not
+set and the variable does not exist then null is returned.
+
+ CV* perl_get_cv _((char* name, I32 create));
+
+=item perl_get_hv
+
+Returns the HV of the specified Perl hash. If C<create> is set and the Perl
+variable does not exist then it will be created. If C<create> is not
+set and the variable does not exist then null is returned.
+
+ HV* perl_get_hv _((char* name, I32 create));
+
+=item perl_get_sv
+
+Returns the SV of the specified Perl scalar. If C<create> is set and the
+Perl variable does not exist then it will be created. If C<create> is not
+set and the variable does not exist then null is returned.
+
+ SV* perl_get_sv _((char* name, I32 create));
+
+=item perl_parse
+
+Tells a Perl interpreter to parse a Perl script. See L<perlembed>.
+
+=item perl_require_pv
+
+Tells Perl to C<require> a module.
+
+ void perl_require_pv _((char* pv));
+
+=item perl_run
+
+Tells a Perl interpreter to run. See L<perlembed>.
+
+=item POPi
+
+Pops an integer off the stack.
+
+ int POPi();
+
+=item POPl
+
+Pops a long off the stack.
+
+ long POPl();
+
+=item POPp
+
+Pops a string off the stack.
+
+ char * POPp();
+
+=item POPn
+
+Pops a double off the stack.
+
+ double POPn();
+
+=item POPs
+
+Pops an SV off the stack.
+
+ SV* POPs();
+
+=item PUSHMARK
+
+Opening bracket for arguments on a callback. See C<PUTBACK> and L<perlcall>.
+
+ PUSHMARK(p)
+
+=item PUSHi
+
+Push an integer onto the stack. The stack must have room for this element.
+See C<XPUSHi>.
+
+ PUSHi(int d)
+
+=item PUSHn
+
+Push a double onto the stack. The stack must have room for this element.
+See C<XPUSHn>.
+
+ PUSHn(double d)
+
+=item PUSHp
+
+Push a string onto the stack. The stack must have room for this element.
+The C<len> indicates the length of the string. See C<XPUSHp>.
+
+ PUSHp(char *c, int len )
+
+=item PUSHs
+
+Push an SV onto the stack. The stack must have room for this element. See
+C<XPUSHs>.
+
+ PUSHs(sv)
+
+=item PUTBACK
+
+Closing bracket for XSUB arguments. This is usually handled by C<xsubpp>.
+See C<PUSHMARK> and L<perlcall> for other uses.
+
+ PUTBACK;
+
+=item Renew
+
+The XSUB-writer's interface to the C C<realloc> function.
+
+ void * Renew( void *ptr, int size, type )
+
+=item Renewc
+
+The XSUB-writer's interface to the C C<realloc> function, with cast.
+
+ void * Renewc( void *ptr, int size, type, cast )
+
+=item RETVAL
+
+Variable which is setup by C<xsubpp> to hold the return value for an XSUB.
+This is always the proper type for the XSUB. See L<perlxs>.
+
+=item safefree
+
+The XSUB-writer's interface to the C C<free> function.
+
+=item safemalloc
+
+The XSUB-writer's interface to the C C<malloc> function.
+
+=item saferealloc
+
+The XSUB-writer's interface to the C C<realloc> function.
+
+=item savepv
+
+Copy a string to a safe spot. This does not use an SV.
+
+ char* savepv _((char* sv));
+
+=item savepvn
+
+Copy a string to a safe spot. The C<len> indicates number of bytes to
+copy. This does not use an SV.
+
+ char* savepvn _((char* sv, I32 len));
+
+=item SAVETMPS
+
+Opening bracket for temporaries on a callback. See C<FREETMPS> and
+L<perlcall>.
+
+ SAVETMPS;
+
+=item SP
+
+Stack pointer. This is usually handled by C<xsubpp>. See C<dSP> and
+C<SPAGAIN>.
+
+=item SPAGAIN
+
+Refetch the stack pointer. Used after a callback. See L<perlcall>.
+
+ SPAGAIN;
+
+=item ST
+
+Used to access elements on the XSUB's stack.
+
+ SV* ST(int x)
+
+=item strEQ
+
+Test two strings to see if they are equal. Returns true or false.
+
+ int strEQ( char *s1, char *s2 )
+
+=item strGE
+
+Test two strings to see if the first, C<s1>, is greater than or equal to the
+second, C<s2>. Returns true or false.
+
+ int strGE( char *s1, char *s2 )
+
+=item strGT
+
+Test two strings to see if the first, C<s1>, is greater than the second,
+C<s2>. Returns true or false.
+
+ int strGT( char *s1, char *s2 )
+
+=item strLE
+
+Test two strings to see if the first, C<s1>, is less than or equal to the
+second, C<s2>. Returns true or false.
+
+ int strLE( char *s1, char *s2 )
+
+=item strLT
+
+Test two strings to see if the first, C<s1>, is less than the second,
+C<s2>. Returns true or false.
+
+ int strLT( char *s1, char *s2 )
+
+=item strNE
+
+Test two strings to see if they are different. Returns true or false.
+
+ int strNE( char *s1, char *s2 )
+
+=item strnEQ
+
+Test two strings to see if they are equal. The C<len> parameter indicates
+the number of bytes to compare. Returns true or false.
+
+ int strnEQ( char *s1, char *s2 )
+
+=item strnNE
+
+Test two strings to see if they are different. The C<len> parameter
+indicates the number of bytes to compare. Returns true or false.
+
+ int strnNE( char *s1, char *s2, int len )
+
+=item sv_2mortal
+
+Marks an SV as mortal. The SV will be destroyed when the current context
+ends.
+
+ SV* sv_2mortal _((SV* sv));
+
+=item sv_bless
+
+Blesses an SV into a specified package. The SV must be an RV. The package
+must be designated by its stash (see C<gv_stashpv()>). The refcount of the
+SV is unaffected.
+
+ SV* sv_bless _((SV* sv, HV* stash));
+
+=item sv_catpv
+
+Concatenates the string onto the end of the string which is in the SV.
+
+ void sv_catpv _((SV* sv, char* ptr));
+
+=item sv_catpvn
+
+Concatenates the string onto the end of the string which is in the SV. The
+C<len> indicates number of bytes to copy.
+
+ void sv_catpvn _((SV* sv, char* ptr, STRLEN len));
+
+=item sv_catsv
+
+Concatentates the string from SV C<ssv> onto the end of the string in SV
+C<dsv>.
+
+ void sv_catsv _((SV* dsv, SV* ssv));
+
+=item SvCUR
+
+Returns the length of the string which is in the SV. See C<SvLEN>.
+
+ int SvCUR (SV* sv)
+
+=item SvCUR_set
+
+Set the length of the string which is in the SV. See C<SvCUR>.
+
+ SvCUR_set (SV* sv, int val )
+
+=item SvEND
+
+Returns a pointer to the last character in the string which is in the SV.
+See C<SvCUR>. Access the character as
+
+ *SvEND(sv)
+
+=item SvGROW
+
+Expands the character buffer in the SV.
+
+ char * SvGROW( SV* sv, int len )
+
+=item SvIOK
+
+Returns a boolean indicating whether the SV contains an integer.
+
+ int SvIOK (SV* SV)
+
+=item SvIOK_off
+
+Unsets the IV status of an SV.
+
+ SvIOK_off (SV* sv)
+
+=item SvIOK_on
+
+Tells an SV that it is an integer.
+
+ SvIOK_on (SV* sv)
+
+=item SvIOKp
+
+Returns a boolean indicating whether the SV contains an integer. Checks the
+B<private> setting. Use C<SvIOK>.
+
+ int SvIOKp (SV* SV)
+
+=item sv_isa
+
+Returns a boolean indicating whether the SV is blessed into the specified
+class. This does not know how to check for subtype, so it doesn't work in
+an inheritance relationship.
+
+ int sv_isa _((SV* sv, char* name));
+
+=item SvIV
+
+Returns the integer which is in the SV.
+
+ int SvIV (SV* sv)
+
+=item sv_isobject
+
+Returns a boolean indicating whether the SV is an RV pointing to a blessed
+object. If the SV is not an RV, or if the object is not blessed, then this
+will return false.
+
+ int sv_isobject _((SV* sv));
+
+=item SvIVX
+
+Returns the integer which is stored in the SV.
+
+ int SvIVX (SV* sv);
+
+=item SvLEN
+
+Returns the size of the string buffer in the SV. See C<SvCUR>.
+
+ int SvLEN (SV* sv)
+
+=item sv_magic
+
+Adds magic to an SV.
+
+ void sv_magic _((SV* sv, SV* obj, int how, char* name, I32 namlen));
+
+=item sv_mortalcopy
+
+Creates a new SV which is a copy of the original SV. The new SV is marked
+as mortal.
+
+ SV* sv_mortalcopy _((SV* oldsv));
+
+=item SvOK
+
+Returns a boolean indicating whether the value is an SV.
+
+ int SvOK (SV* sv)
+
+=item sv_newmortal
+
+Creates a new SV which is mortal. The refcount of the SV is set to 1.
+
+ SV* sv_newmortal _((void));
+
+=item sv_no
+
+This is the C<false> SV. See C<sv_yes>. Always refer to this as C<&sv_no>.
+
+=item SvNIOK
+
+Returns a boolean indicating whether the SV contains a number, integer or
+double.
+
+ int SvNIOK (SV* SV)
+
+=item SvNIOK_off
+
+Unsets the NV/IV status of an SV.
+
+ SvNIOK_off (SV* sv)
+
+=item SvNIOKp
+
+Returns a boolean indicating whether the SV contains a number, integer or
+double. Checks the B<private> setting. Use C<SvNIOK>.
+
+ int SvNIOKp (SV* SV)
+
+=item SvNOK
+
+Returns a boolean indicating whether the SV contains a double.
+
+ int SvNOK (SV* SV)
+
+=item SvNOK_off
+
+Unsets the NV status of an SV.
+
+ SvNOK_off (SV* sv)
+
+=item SvNOK_on
+
+Tells an SV that it is a double.
+
+ SvNOK_on (SV* sv)
+
+=item SvNOKp
+
+Returns a boolean indicating whether the SV contains a double. Checks the
+B<private> setting. Use C<SvNOK>.
+
+ int SvNOKp (SV* SV)
+
+=item SvNV
+
+Returns the double which is stored in the SV.
+
+ double SvNV (SV* sv);
+
+=item SvNVX
+
+Returns the double which is stored in the SV.
+
+ double SvNVX (SV* sv);
+
+=item SvPOK
+
+Returns a boolean indicating whether the SV contains a character string.
+
+ int SvPOK (SV* SV)
+
+=item SvPOK_off
+
+Unsets the PV status of an SV.
+
+ SvPOK_off (SV* sv)
+
+=item SvPOK_on
+
+Tells an SV that it is a string.
+
+ SvPOK_on (SV* sv)
+
+=item SvPOKp
+
+Returns a boolean indicating whether the SV contains a character string.
+Checks the B<private> setting. Use C<SvPOK>.
+
+ int SvPOKp (SV* SV)
+
+=item SvPV
+
+Returns a pointer to the string in the SV, or a stringified form of the SV
+if the SV does not contain a string. If C<len> is C<na> then Perl will
+handle the length on its own.
+
+ char * SvPV (SV* sv, int len )
+
+=item SvPVX
+
+Returns a pointer to the string in the SV. The SV must contain a string.
+
+ char * SvPVX (SV* sv)
+
+=item SvREFCNT
+
+Returns the value of the object's refcount.
+
+ int SvREFCNT (SV* sv);
+
+=item SvREFCNT_dec
+
+Decrements the refcount of the given SV.
+
+ void SvREFCNT_dec (SV* sv)
+
+=item SvREFCNT_inc
+
+Increments the refcount of the given SV.
+
+ void SvREFCNT_inc (SV* sv)
+
+=item SvROK
+
+Tests if the SV is an RV.
+
+ int SvROK (SV* sv)
+
+=item SvROK_off
+
+Unsets the RV status of an SV.
+
+ SvROK_off (SV* sv)
+
+=item SvROK_on
+
+Tells an SV that it is an RV.
+
+ SvROK_on (SV* sv)
+
+=item SvRV
+
+Dereferences an RV to return the SV.
+
+ SV* SvRV (SV* sv);
+
+=item sv_setiv
+
+Copies an integer into the given SV.
+
+ void sv_setiv _((SV* sv, IV num));
+
+=item sv_setnv
+
+Copies a double into the given SV.
+
+ void sv_setnv _((SV* sv, double num));
+
+=item sv_setpv
+
+Copies a string into an SV. The string must be null-terminated.
+
+ void sv_setpv _((SV* sv, char* ptr));
+
+=item sv_setpvn
+
+Copies a string into an SV. The C<len> parameter indicates the number of
+bytes to be copied.
+
+ void sv_setpvn _((SV* sv, char* ptr, STRLEN len));
+
+=item sv_setref_iv
+
+Copies an integer into an SV, optionally blessing the SV. The SV must be an
+RV. The C<classname> argument indicates the package for the blessing. Set
+C<classname> to C<Nullch> to avoid the blessing. The new SV will be
+returned and will have a refcount of 1.
+
+ SV* sv_setref_iv _((SV *rv, char *classname, IV iv));
+
+=item sv_setref_nv
+
+Copies a double into an SV, optionally blessing the SV. The SV must be an
+RV. The C<classname> argument indicates the package for the blessing. Set
+C<classname> to C<Nullch> to avoid the blessing. The new SV will be
+returned and will have a refcount of 1.
+
+ SV* sv_setref_nv _((SV *rv, char *classname, double nv));
+
+=item sv_setref_pv
+
+Copies a pointer into an SV, optionally blessing the SV. The SV must be an
+RV. If the C<pv> argument is NULL then C<sv_undef> will be placed into the
+SV. The C<classname> argument indicates the package for the blessing. Set
+C<classname> to C<Nullch> to avoid the blessing. The new SV will be
+returned and will have a refcount of 1.
+
+ SV* sv_setref_pv _((SV *rv, char *classname, void* pv));
+
+Do not use with integral Perl types such as HV, AV, SV, CV, because those
+objects will become corrupted by the pointer copy process.
+
+Note that C<sv_setref_pvn> copies the string while this copies the pointer.
+
+=item sv_setref_pvn
+
+Copies a string into an SV, optionally blessing the SV. The lenth of the
+string must be specified with C<n>. The SV must be an RV. The C<classname>
+argument indicates the package for the blessing. Set C<classname> to
+C<Nullch> to avoid the blessing. The new SV will be returned and will have
+a refcount of 1.
+
+ SV* sv_setref_pvn _((SV *rv, char *classname, char* pv, I32 n));
+
+Note that C<sv_setref_pv> copies the pointer while this copies the string.
+
+=item sv_setsv
+
+Copies the contents of the source SV C<ssv> into the destination SV C<dsv>.
+
+ void sv_setsv _((SV* dsv, SV* ssv));
+
+=item SvSTASH
+
+Returns the stash of the SV.
+
+ HV * SvSTASH (SV* sv)
+
+=item SVt_IV
+
+Integer type flag for scalars. See C<svtype>.
+
+=item SVt_PV
+
+Pointer type flag for scalars. See C<svtype>.
+
+=item SVt_PVAV
+
+Type flag for arrays. See C<svtype>.
+
+=item SVt_PVCV
+
+Type flag for code refs. See C<svtype>.
+
+=item SVt_PVHV
+
+Type flag for hashes. See C<svtype>.
+
+=item SVt_PVMG
+
+Type flag for blessed scalars. See C<svtype>.
+
+=item SVt_NV
+
+Double type flag for scalars. See C<svtype>.
+
+=item SvTRUE
+
+Returns a boolean indicating whether Perl would evaluate the SV as true or
+false, defined or undefined.
+
+ int SvTRUE (SV* sv)
+
+=item SvTYPE
+
+Returns the type of the SV. See C<svtype>.
+
+ svtype SvTYPE (SV* sv)
+
+=item svtype
+
+An enum of flags for Perl types. These are found in the file B<sv.h> in the
+C<svtype> enum. Test these flags with the C<SvTYPE> macro.
+
+=item SvUPGRADE
+
+Used to upgrade an SV to a more complex form. See C<svtype>.
+
+=item sv_undef
+
+This is the C<undef> SV. Always refer to this as C<&sv_undef>.
+
+=item sv_usepvn
+
+Tells an SV to use C<ptr> to find its string value. Normally the string is
+stored inside the SV; this allows the SV to use an outside string. The
+string length, C<len>, must be supplied. This function will realloc the
+memory pointed to by C<ptr>, so that pointer should not be freed or used by
+the programmer after giving it to sv_usepvn.
+
+ void sv_usepvn _((SV* sv, char* ptr, STRLEN len));
+
+=item sv_yes
+
+This is the C<true> SV. See C<sv_no>. Always refer to this as C<&sv_yes>.
+
+=item THIS
+
+Variable which is setup by C<xsubpp> to designate the object in a C++ XSUB.
+This is always the proper type for the C++ object. See C<CLASS> and
+L<perlxs>.
+
+=item toLOWER
+
+Converts the specified character to lowercase.
+
+ int toLOWER (char c)
+
+=item toUPPER
+
+Converts the specified character to uppercase.
+
+ int toUPPER (char c)
+
+=item warn
+
+This is the XSUB-writer's interface to Perl's C<warn> function. Use this
+function the same way you use the C C<printf> function. See C<croak()>.
+
+=item XPUSHi
+
+Push an integer onto the stack, extending the stack if necessary. See
+C<PUSHi>.
+
+ XPUSHi(int d)
+
+=item XPUSHn
+
+Push a double onto the stack, extending the stack if necessary. See
+C<PUSHn>.
+
+ XPUSHn(double d)
+
+=item XPUSHp
+
+Push a string onto the stack, extending the stack if necessary. The C<len>
+indicates the length of the string. See C<PUSHp>.
+
+ XPUSHp(char *c, int len)
+
+=item XPUSHs
+
+Push an SV onto the stack, extending the stack if necessary. See C<PUSHs>.
+
+ XPUSHs(sv)
+
+=item XSRETURN
+
+Return from XSUB, indicating number of items on the stack. This is usually
+handled by C<xsubpp>.
+
+ XSRETURN(x);
+
+=item XSRETURN_EMPTY
+
+Return from an XSUB immediately.
+
+ XSRETURN_EMPTY;
+
+=item XSRETURN_NO
+
+Return C<false> from an XSUB immediately.
+
+ XSRETURN_NO;
+
+=item XSRETURN_UNDEF
+
+Return C<undef> from an XSUB immediately.
+
+ XSRETURN_UNDEF;
+
+=item XSRETURN_YES
+
+Return C<true> from an XSUB immediately.
+
+ XSRETURN_YES;
+
+=item Zero
+
+The XSUB-writer's interface to the C C<memzero> function. The C<d> is the
+destination, C<n> is the number of items, and C<t> is the type.
+
+ (void) Zero( d, n, t );
+
+=back
+
+=head1 AUTHOR
+
+Jeff Okamoto <okamoto@corp.hp.com>
+
+With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
+Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
+Bowers, Matthew Green, Tim Bunce, and Spider Boardman.
+
+API Listing by Dean Roehrich <roehrich@cray.com>.
+
+=head1 DATE
+
+Version 20: 1995/12/14
-Version 19: 1995/4/26
=head1 NAME
-perlipc - Perl interprocess communication (signals, fifos, pipes, safe
-subprocceses, sockets, and semaphores)
+perlipc - Perl interprocess communication (signals, fifos, pipes, safe subprocceses, sockets, and semaphores)
=head1 DESCRIPTION
-=head1 TITLE
+=head1 NAME
perlLoL - Manipulating Lists of Lists in Perl
-=head1 Declaration and Access
+=head1 DESCRIPTION
+
+=head1 Declaration and Access of Lists of Lists
The simplest thing to build is a list of lists (sometimes called an array
of arrays). It's reasonably easy to understand, and almost everything
}
-=head1 Passing Arguments
-
-One place where a list of lists crops up is when you pass
-in several list references to a function. Consider:
-
- @tailings = popmany ( \@a, \@b, \@c, \@d );
-
- sub popmany {
- my $aref;
- my @retlist = ();
- foreach $aref ( @_ ) {
- push @retlist, pop @$aref;
- }
- return @retlist;
- }
-
-This function was designed to pop off the last element from each of
-its arguments and return those in a list. In this function,
-you can think of @_ as a list of lists.
-
-Just as a side note, what happens if the function is called with the
-"wrong" types of arguments? Normally nothing, but in the case of
-references, we can be a bit pickier. This isn't detectable at
-compile-time (yet--Larry does have a prototype prototype in the works for
-5.002), but you could check it at run time using the ref() function.
-
- use Carp;
- for $i ( 0 .. $#_) {
- if (ref($_[$i]) ne 'ARRAY') {
- confess "popmany: arg $i not an array reference\n";
- }
- }
-
-However, that's not usually necessary unless you want to trap it. It's
-also dubious in that it would fail on a real array references blessed into
-its own class (an object). But since you're all going to be using
-C<strict refs>, it would raise an exception anyway even without the die.
-
-This will matter more to you later on when you start building up
-more complex data structures that all aren't woven of the same
-cloth, so to speak.
-
=head1 SEE ALSO
perldata(1), perlref(1), perldsc(1)
=head2 Packages
Perl provides a mechanism for alternative namespaces to protect packages
-from stomping on each others variables. In fact, apart from certain magical
-variables, there's really no such thing as a global variable in Perl.
-By default, a Perl script starts
-compiling into the package known as C<main>. You can switch namespaces
-using the C<package> declaration. The scope of the package declaration is
-from the declaration itself to the end of the enclosing block (the same
-scope as the local() operator). Typically it would be the first
-declaration in a file to be included by the C<require> operator. You can
+from stomping on each others variables. In fact, apart from certain
+magical variables, there's really no such thing as a global variable in
+Perl. The package statement declares the compilation unit as being in the
+given namespace. The scope of the package declaration is from the
+declaration itself through the end of the enclosing block (the same scope
+as the local() operator). All further unqualified dynamic identifiers
+will be in this namespace. A package statement only affects dynamic
+variables--including those you've used local() on--but I<not> lexical
+variables created with my(). Typically it would be the first declaration
+in a file to be included by the C<require> or C<use> operator. You can
switch into a package in more than one place; it merely influences which
symbol table is used by the compiler for the rest of that block. You can
refer to variables and filehandles in other packages by prefixing the
It would treat package C<INNER> as a totally separate global package.
Only identifiers starting with letters (or underscore) are stored in a
-package's symbol table. All other symbols are kept in package C<main>.
-In addition, the identifiers STDIN, STDOUT, STDERR, ARGV,
-ARGVOUT, ENV, INC and SIG are forced to be in package C<main>,
-even when used for other purposes than their built-in one. Note also
-that, if you have a package called C<m>, C<s> or C<y>, then you can't use
-the qualified form of an identifier because it will be interpreted instead
-as a pattern match, a substitution, or a translation.
+package's symbol table. All other symbols are kept in package C<main>,
+including all of the punctuation variables like $_. In addition, the
+identifiers STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC and SIG are
+forced to be in package C<main>, even when used for other purposes than
+their built-in one. Note also that, if you have a package called C<m>,
+C<s> or C<y>, then you can't use the qualified form of an identifier
+because it will be interpreted instead as a pattern match, a substitution,
+or a translation.
(Variables beginning with underscore used to be forced into package
main, but we decided it was more useful for package writers to be able
-to use leading underscore to indicate private variables and method names.)
+to use leading underscore to indicate private variables and method names.
+$_ is still global though.)
Eval()ed strings are compiled in the package in which the eval() was
compiled. (Assignments to C<$SIG{}>, however, assume the signal
expressions in the context of the C<main> package (or wherever you came
from). See L<perldebug>.
+See L<perlsub> for other scoping issues related to my() and local(),
+or L<perlref> regarding closures.
+
=head2 Symbol Tables
The symbol table for a package happens to be stored in the associative
name is thus C<%main::>, or C<%::> for short. Likewise the nested package
mentioned earlier is named C<%OUTER::INNER::>.
-The value in each entry of the associative array is what you are
-referring to when you use the C<*name> typeglob notation. In fact, the following
-have the same effect, though the first is more efficient because it
-does the symbol table lookups at compile time:
+The value in each entry of the associative array is what you are referring
+to when you use the C<*name> typeglob notation. In fact, the following
+have the same effect, though the first is more efficient because it does
+the symbol table lookups at compile time:
local(*main::foo) = *main::bar; local($main::{'foo'}) =
$main::{'bar'};
the name of the subroutine is qualified so that its name is inserted
into package C<main>.
-Assignment to a typeglob performs an aliasing operation,
-i.e.,
+Assignment to a typeglob performs an aliasing operation, i.e.,
*dick = *richard;
makes $richard and $dick the same variable, but leaves
@richard and @dick as separate arrays. Tricky, eh?
+This mechanism may be used to pass and return cheap references
+into or from subroutines if you won't want to copy the whole
+thing.
+
+ %some_hash = ();
+ *some_hash = fn( \%another_hash );
+ sub fn {
+ local *hashsym = shift;
+ # now use %hashsym normally, and you
+ # will affect the caller's %another_hash
+ my %nhash = (); # do what you want
+ return \%nhash;
+ }
+
+On return, the reference wil overwrite the hash slot in the
+symbol table specified by the *some_hash typeglob. This
+is a somewhat tricky way of passing around refernces cheaply
+when you won't want to have to remember to dereference variables
+explicitly.
+
+Another use of symbol tables is for making "constant" scalars.
+
+ *PI = \3.14159265358979;
+
+Now you cannot alter $PI, which is probably a good thing all in all.
+
=head2 Package Constructors and Destructors
There are two special subroutine definitions that function as package
BEGIN { require "Module.pm"; import Module LIST; }
+As a special case
+
+ use Module ();
+
+is exactly equivalent to
+
+ BEGIN { require "Module.pm"; }
+
All Perl module files have the extension F<.pm>. C<use> assumes this so
that you don't have to spell out "F<Module.pm>" in quotes. This also
helps to differentiate new modules from old F<.pl> and F<.ph> files.
to function as a pragma mechanism, and also how modules are able to
declare subroutines that are then visible as list operators for
the rest of the current file. This will not work if you use C<require>
-instead of C<use>. Therefore, if you're planning on the module altering
-your namespace, use C<use>; otherwise, use C<require>. Otherwise you
-can get into this problem:
+instead of C<use>. With require you can get into this problem:
require Cwd; # make Cwd:: accessible
$here = Cwd::getcwd();
require Cwd; # make Cwd:: accessible
$here = getcwd(); # oops! no main::getcwd()
+In general C<use Module ();> is recommended over C<require Module;>.
+
Perl packages may be nested inside other package names, so we can have
package names containing C<::>. But if we used that package name
directly as a filename it would makes for unwieldy or impossible
=over 12
-=item C<diagnostics>
+=item diagnostics
Pragma to produce enhanced diagnostics
-=item C<integer>
+=item integer
Pragma to compute arithmetic in integer instead of double
-=item C<less>
+=item less
Pragma to request less of something from the compiler
-=item C<sigtrap>
+=item overload
+
+Pragma for overloading operators
+
+=item sigtrap
Pragma to enable stack backtrace on unexpected signals
-=item C<strict>
+=item strict
Pragma to restrict unsafe constructs
-=item C<subs>
+=item subs
Pragma to predeclare sub names
manner with respect to namespace pollution because they use the
Exporter module. See their own documentation for details.
-To find out all the modules installed on your system, do this:
+=over 12
+
+=item AnyDBM_File
+
+provide framework for multiple DBMs
+
+=item AutoLoader
+
+load functions only on demand
+
+=item AutoSplit
+
+split a package for autoloading
+
+=item Benchmark
+
+benchmark running times of code
+
+=item Carp
+
+warn of errors (from perspective of caller)
+
+=item Config
+
+access Perl configuration option
+
+=item Cwd
+
+get pathname of current working directory
+
+=item DB_File
+
+Perl access to Berkeley DB
+
+=item Devel::SelfStubber
+
+generate stubs for a SelfLoading module
+
+=item DynaLoader
+
+Dynamically load C libraries into Perl code
+
+=item English
+
+use nice English (or awk) names for ugly punctuation variables
+
+=item Env
+
+perl module that imports environment variables
+
+=item Exporter
+
+provide inport/export controls for Perl modules
+
+=item ExtUtils::Liblist
+
+determine libraries to use and how to use them
+
+=item ExtUtils::MakeMaker
+
+create an extension Makefile
+
+=item ExtUtils::Manifest
+
+utilities to write and check a MANIFEST file
+
+=item ExtUtils::Mkbootstrap
+
+make a bootstrap file for use by DynaLoader
+
+=item ExtUtils::Miniperl
+
+!!!GOOD QUESTION!!!
+
+=item Fcntl
+
+load the C Fcntl.h defines
+
+=item File::Basename
+
+parse file specifications
+
+=item File::CheckTree
+
+run many filetest checks on a tree
+
+=item File::Find
+
+traverse a file tree
+
+=item FileHandle
+
+supply object methods for filehandles
+
+=item File::Path
+
+create or remove a series of directories
+
+=item Getopt::Long
+
+extended getopt processing
+
+=item Getopt::Std
+
+Process single-character switches with switch clustering
+
+=item I18N::Collate
+
+compare 8-bit scalar data according to the current locale
+
+=item IPC::Open2
+
+a process for both reading and writing
+
+=item IPC::Open3
+
+open a process for reading, writing, and error handling
+
+=item Net::Ping
+
+check a host for upness
+
+=item POSIX
+
+Perl interface to IEEE Std 1003.1
+
+=item SelfLoader
+
+load functions only on demand
+
+=item Socket
+
+load the C socket.h defines and structure manipulators
+
+=item Test::Harness
+
+run perl standard test scripts with statistics
+
+=item Text::Abbrev
+
+rceate an abbreviation table from a list
+
+=back
+
+To find out I<all> the modules installed on your system, including
+those without documentation or outside the standard release, do this:
find `perl -e 'print "@INC"'` -name '*.pm' -print
dynamically loaded into Perl if and when you need them. Supported
extension modules include the Socket, Fcntl, and POSIX modules.
-Many popular C extension modules
-do not come bundled (at least, not completely)
-due to their size, volatility, or simply lack of time for adequate testing
-and configuration across the multitude of platforms on which Perl was
-beta-tested. You are encouraged to look for them in archie(1L), the Perl
-FAQ or Meta-FAQ, the WWW page, and even with their authors before randomly
-posting asking for their present condition and disposition.
+Many popular C extension modules do not come bundled (at least, not
+completely) due to their size, volatility, or simply lack of time for
+adequate testing and configuration across the multitude of platforms on
+which Perl was beta-tested. You are encouraged to look for them in
+archie(1L), the Perl FAQ or Meta-FAQ, the WWW page, and even with their
+authors before randomly posting asking for their present condition and
+disposition.
-=head2 CPAN
+=head1 CPAN
CPAN stands for the Comprehensive Perl Archive Network. This is a globally
replicated collection of all known Perl materials, including hundreds
=back
For an up-to-date listing of CPAN sites,
-see http://www.perl.com/perl/ or ftp://ftp.perl.com/perl/.
+see http://www.perl.com/perl/ or ftp://ftp.perl.com/perl/ .
+
+=head1 Modules: Creation, Use and Abuse
+
+(The following section is borrowed directly from Tim Bunce's modules
+file, available at your nearest CPAN site.)
+
+Perl 5 implements a class using a package, but the presence of a
+package doesn't imply the presence of a class. A package is just a
+namespace. A class is a package that provides subroutines that can be
+used as methods. A method is just a subroutine that expects, as its
+first argument, either the name of a package (for "static" methods),
+or a reference to something (for "virtual" methods).
+
+A module is a file that (by convention) provides a class of the same
+name (sans the .pm), plus an import method in that class that can be
+called to fetch exported symbols. This module may implement some of
+its methods by loading dynamic C or C++ objects, but that should be
+totally transparent to the user of the module. Likewise, the module
+might set up an AUTOLOAD function to slurp in subroutine definitions on
+demand, but this is also transparent. Only the .pm file is required to
+exist.
+
+=head2 Guidelines for Module Creation
+
+=over 4
+
+=item Do similar modules already exist in some form?
+
+If so, please try to reuse the existing modules either in whole or
+by inheriting useful features into a new class. If this is not
+practical try to get together with the module authors to work on
+extending or enhancing the functionality of the existing modules.
+A perfect example is the plethora of packages in perl4 for dealing
+with command line options.
+
+If you are writing a module to expand an already existing set of
+modules, please coordinate with the author of the package. It
+helps if you follow the same naming scheme and module interaction
+scheme as the original author.
+
+=item Try to design the new module to be easy to extend and reuse.
+
+Use blessed references. Use the two argument form of bless to bless
+into the class name given as the first parameter of the constructor,
+e.g.:
+
+ sub new {
+ my $class = shift;
+ return bless {}, $class;
+ }
+
+or even this if you'd like it to be used as either a static
+or a virtual method.
+
+ sub new {
+ my $self = shift;
+ my $class = ref($self) || $self;
+ return bless {}, $class;
+ }
+
+Pass arrays as references so more parameters can be added later
+(it's also faster). Convert functions into methods where
+appropriate. Split large methods into smaller more flexible ones.
+Inherit methods from other modules if appropriate.
+
+Avoid class name tests like: die "Invalid" unless ref $ref eq 'FOO'.
+Generally you can delete the "eq 'FOO'" part with no harm at all.
+Let the objects look after themselves! Generally, avoid hardwired
+class names as far as possible.
+
+Avoid $r->Class::func() where using @ISA=qw(... Class ...) and
+$r->func() would work (see perlbot man page for more details).
+
+Use autosplit so little used or newly added functions won't be a
+burden to programs which don't use them. Add test functions to
+the module after __END__ either using AutoSplit or by saying:
+
+ eval join('',<main::DATA>) || die $@ unless caller();
+
+Does your module pass the 'empty sub-class' test? If you say
+"@SUBCLASS::ISA = qw(YOURCLASS);" your applications should be able
+to use SUBCLASS in exactly the same way as YOURCLASS. For example,
+does your application still work if you change: $obj = new YOURCLASS;
+into: $obj = new SUBCLASS; ?
+
+Avoid keeping any state information in your packages. It makes it
+difficult for multiple other packages to use yours. Keep state
+information in objects.
+
+Always use C<-w>. Try to C<use strict;> (or C<use strict qw(...);>).
+Remember that you can add C<no strict qw(...);> to individual blocks
+of code which need less strictness. Always use C<-w>. Always use C<-w>!
+Follow the guidelines in the perlstyle(1) manual.
+
+=item Some simple style guidelines
+
+The perlstyle manual supplied with perl has many helpful points.
+
+Coding style is a matter of personal taste. Many people evolve their
+style over several years as they learn what helps them write and
+maintain good code. Here's one set of assorted suggestions that
+seem to be widely used by experienced developers:
+
+Use underscores to separate words. It is generally easier to read
+$var_names_like_this than $VarNamesLikeThis, especially for
+non-native speakers of English. It's also a simple rule that works
+consistently with VAR_NAMES_LIKE_THIS.
+
+Package/Module names are an exception to this rule. Perl informally
+reserves lowercase module names for 'pragma' modules like integer
+and strict. Other modules normally begin with a capital letter and
+use mixed case with no underscores (need to be short and portable).
+
+You may find it helpful to use letter case to indicate the scope
+or nature of a variable. For example:
+
+ $ALL_CAPS_HERE constants only (beware clashes with perl vars)
+ $Some_Caps_Here package-wide global/static
+ $no_caps_here function scope my() or local() variables
+
+Function and method names seem to work best as all lowercase.
+E.g., $obj->as_string().
+
+You can use a leading underscore to indicate that a variable or
+function should not be used outside the package that defined it.
+
+=item Select what to export.
+
+Do NOT export method names!
+
+Do NOT export anything else by default without a good reason!
+
+Exports pollute the namespace of the module user. If you must
+export try to use @EXPORT_OK in preference to @EXPORT and avoid
+short or common names to reduce the risk of name clashes.
+
+Generally anything not exported is still accessible from outside the
+module using the ModuleName::item_name (or $blessed_ref->method)
+syntax. By convention you can use a leading underscore on names to
+informally indicate that they are 'internal' and not for public use.
+
+(It is actually possible to get private functions by saying:
+my $subref = sub { ... }; &$subref; But there's no way to call that
+directly as a method, since a method must have a name in the symbol
+table.)
+
+As a general rule, if the module is trying to be object oriented
+then export nothing. If it's just a collection of functions then
+@EXPORT_OK anything but use @EXPORT with caution.
+
+=item Select a name for the module.
+
+This name should be as descriptive, accurate and complete as
+possible. Avoid any risk of ambiguity. Always try to use two or
+more whole words. Generally the name should reflect what is special
+about what the module does rather than how it does it. Please use
+nested module names to informally group or categorise a module.
+A module should have a very good reason not to have a nested name.
+Module names should begin with a capital letter.
+
+Having 57 modules all called Sort will not make life easy for anyone
+(though having 23 called Sort::Quick is only marginally better :-).
+Imagine someone trying to install your module alongside many others.
+If in any doubt ask for suggestions in comp.lang.perl.misc.
+
+If you are developing a suite of related modules/classes it's good
+practice to use nested classes with a common prefix as this will
+avoid namespace clashes. For example: Xyz::Control, Xyz::View,
+Xyz::Model etc. Use the modules in this list as a naming guide.
+
+If adding a new module to a set, follow the original author's
+standards for naming modules and the interface to methods in
+those modules.
+
+To be portable each component of a module name should be limited to
+11 characters. If it might be used on DOS then try to ensure each is
+unique in the first 8 characters. Nested modules make this easier.
+
+=item Have you got it right?
+
+How do you know that you've made the right decisions? Have you
+picked an interface design that will cause problems later? Have
+you picked the most appropriate name? Do you have any questions?
+
+The best way to know for sure, and pick up many helpful suggestions,
+is to ask someone who knows. Comp.lang.perl.misc is read by just about
+all the people who develop modules and it's the best place to ask.
+
+All you need to do is post a short summary of the module, its
+purpose and interfaces. A few lines on each of the main methods is
+probably enough. (If you post the whole module it might be ignored
+by busy people - generally the very people you want to read it!)
+
+Don't worry about posting if you can't say when the module will be
+ready - just say so in the message. It might be worth inviting
+others to help you, they may be able to complete it for you!
+
+=item README and other Additional Files.
+
+It's well known that software developers usually fully document the
+software they write. If, however, the world is in urgent need of
+your software and there is not enough time to write the full
+documentation please at least provide a README file containing:
+
+=over 10
+
+=item *
+A description of the module/package/extension etc.
+
+=item *
+A copyright notice - see below.
+
+=item *
+Prerequisites - what else you may need to have.
+
+=item *
+How to build it - possible changes to Makefile.PL etc.
+
+=item *
+How to install it.
+
+=item *
+Recent changes in this release, especially incompatibilities
+
+=item *
+Changes / enhancements you plan to make in the future.
+
+=back
+
+If the README file seems to be getting too large you may wish to
+split out some of the sections into separate files: INSTALL,
+Copying, ToDo etc.
+
+=item Adding a Copyright Notice.
+
+How you choose to licence your work is a personal decision.
+The general mechanism is to assert your Copyright and then make
+a declaration of how others may copy/use/modify your work.
+
+Perl, for example, is supplied with two types of licence: The GNU
+GPL and The Artistic License (see the files README, Copying and
+Artistic). Larry has good reasons for NOT just using the GNU GPL.
+
+My personal recommendation, out of respect for Larry, Perl and the
+perl community at large is to simply state something like:
+
+ Copyright (c) 1995 Your Name. All rights reserved.
+ This program is free software; you can redistribute it and/or
+ modify it under the same terms as Perl itself.
+
+This statement should at least appear in the README file. You may
+also wish to include it in a Copying file and your source files.
+Remember to include the other words in addition to the Copyright.
+
+=item Give the module a version/issue/release number.
+
+To be fully compatible with the Exporter and MakeMaker modules you
+should store your module's version number in a non-my package
+variable called $VERSION. This should be a valid floating point
+number with at least two digits after the decimal (ie hundredths,
+e.g, $VERSION = "0.01"). Don't use a "1.3.2" style version.
+See Exporter.pm in Perl5.001m or later for details.
+
+It may be handy to add a function or method to retrieve the number.
+Use the number in announcements and archive file names when
+releasing the module (ModuleName-1.02.tar.Z).
+See perldoc ExtUtils::MakeMaker.pm for details.
+
+=item How to release and distribute a module.
+
+It's good idea to post an announcement of the availability of your
+module (or the module itself if small) to the comp.lang.perl.announce
+Usenet newsgroup. This will at least ensure very wide once-off
+distribution.
+
+If possible you should place the module into a major ftp archive and
+include details of it's location in your announcement.
+
+Some notes about ftp archives: Please use a long descriptive file
+name which includes the version number. Most incoming directories
+will not be readable/listable, i.e., you won't be able to see your
+file after uploading it. Remember to send your email notification
+message as soon as possible after uploading else your file may get
+deleted automatically. Allow time for the file to be processed
+and/or check the file has been processed before announcing its
+location.
+
+FTP Archives for Perl Modules:
+
+Follow the instructions and links on
+
+ http://franz.ww.tu-berlin.de/modulelist
+
+or upload to one of these sites:
+
+ ftp://franz.ww.tu-berlin.de/incoming
+ ftp://ftp.cis.ufl.edu/incoming
+
+and notify upload@franz.ww.tu-berlin.de.
+
+By using the WWW interface you can ask the Upload Server to mirror
+your modules from your ftp or WWW site into your own directory on
+CPAN!
+
+Please remember to send me an updated entry for the Module list!
+
+=item Take care when changing a released module.
+
+Always strive to remain compatible with previous released versions
+(see 2.2 above) Otherwise try to add a mechanism to revert to the
+old behaviour if people rely on it. Document incompatible changes.
+
+=back
+
+=head2 Guidelines for Converting Perl 4 Library Scripts into Modules
+
+=over 4
+
+=item There is no requirement to convert anything.
+
+If it ain't broke, don't fix it! Perl 4 library scripts should
+continue to work with no problems. You may need to make some minor
+changes (like escaping non-array @'s in double quoted strings) but
+there is no need to convert a .pl file into a Module for just that.
+
+=item Consider the implications.
+
+All the perl applications which make use of the script will need to
+be changed (slightly) if the script is converted into a module. Is
+it worth it unless you plan to make other changes at the same time?
+
+=item Make the most of the opportunity.
+
+If you are going to convert the script to a module you can use the
+opportunity to redesign the interface. The 'Guidelines for Module
+Creation' above include many of the issues you should consider.
+
+=item The pl2pm utility will get you started.
+
+This utility will read *.pl files (given as parameters) and write
+corresponding *.pm files. The pl2pm utilities does the following:
+
+=over 10
+
+=item *
+Adds the standard Module prologue lines
+
+=item *
+Converts package specifiers from ' to ::
+
+=item *
+Converts die(...) to croak(...)
+
+=item *
+Several other minor changes
+
+=back
+
+Being a mechanical process pl2pm is not bullet proof. The converted
+code will need careful checking, especially any package statements.
+Don't delete the original .pl file till the new .pm one works!
+
+=back
+
+=head2 Guidelines for Reusing Application Code
+
+=over 4
+
+=item Complete applications rarely belong in the Perl Module Library.
+
+=item Many applications contain some perl code which could be reused.
+
+Help save the world! Share your code in a form that makes it easy
+to reuse.
+
+=item Break-out the reusable code into one or more separate module files.
+
+=item Take the opportunity to reconsider and redesign the interfaces.
+
+=item In some cases the 'application' can then be reduced to a small
+
+fragment of code built on top of the reusable modules. In these cases
+the application could invoked as:
+
+ perl -e 'use Module::Name; method(@ARGV)' ...
+or
+ perl -mModule::Name ... (in perl5.002?)
+
+=back
+
Unlike say C++, Perl doesn't provide any special syntax for
constructors. A constructor is merely a subroutine that returns a
-reference that has been "blessed" into a class, generally the
+reference to something "blessed" into a class, generally the
class that the subroutine is defined in. Here is a typical
constructor:
my $self = {}
bless $self;
$self->initialize();
- $self;
+ return $self;
+ }
+
+If you care about inheritance (and you should; see L<perlmod/"Modules:
+Creation, Use and Abuse">), then you want to use the two-arg form of bless
+so that your constructors may be inherited:
+
+ sub new {
+ my $class = shift;
+ my $self = {};
+ bless $self, $class
+ $self->initialize();
+ return $self;
+ }
+
+Or if you expect people to call not just C<CLASS->new()> but also
+C<$obj->new()>, then use something like this. The initialize()
+method used will be of whatever $class we blessed the
+object into:
+
+ sub new {
+ my $this = shift;
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless $self, $class
+ $self->initialize();
+ return $self;
}
Within the class package, the methods will typically deal with the
@ISA array is just the name of another package that happens to be a
class package. The classes are searched (depth first) for missing
methods in the order that they occur in @ISA. The classes accessible
-through @ISA are known as base classes of the current class.
+through @ISA are known as base classes of the current class.
If a missing method is found in one of the base classes, it is cached
in the current class for efficiency. Changing @ISA or defining new
$fred = Critter->MyCritter::find("Fred");
$fred->MyCritter::display('Height', 'Weight');
+If you're trying to control where the method search begins I<and> you're
+executing in the class itself, then you may use the SUPER pseudoclass,
+which says to start looking in your base class's @ISA list without having
+to explicitly name it:
+
+ $self->SUPER::display('Height', 'Weight');
+
+Please note that the C<SUPER::> construct is I<only> meaningful within the
+class.
+
Sometimes you want to call a method when you don't know the method name
ahead of time. You can use the arrow form, replacing the method name
with a simple scalar variable containing the method name:
book about object-oriented design methodology, and bang your forehead
with it for the next six months or so.
+=head2 Two-Phased Garbage Collection
+
+For most purposes, Perl uses a fast and simple reference-based
+garbage collection system. For this reason, there's an extra
+dereference going on at some level, so if you haven't built
+your Perl executable using your C compiler's C<-O> flag, performance
+will suffer. If you I<have> built Perl with C<cc -O>, then this
+probably won't matter.
+
+A more serious concern is that unreachable memory with a non-zero
+reference count will not normally get freed. Therefore, this is a bad
+idea:
+
+ {
+ my $a;
+ $a = \$a;
+ }
+
+Even thought $a I<should> go away, it can't. When building recursive data
+structures, you'll have to break the self-reference yourself explicitly
+if you don't care to leak. For example, here's a self-referential
+node such as one might use in a sophisticated tree structure:
+
+ sub new_node {
+ my $self = shift;
+ my $class = ref($self) || $self;
+ my $node = {};
+ $node->{LEFT} = $node->{RIGHT} = $node;
+ $node->{DATA} = [ @_ ];
+ return bless $node => $class;
+ }
+
+If you create nodes like that, they (currently) won't go away unless you
+break their self reference yourself. (In other words, this is not to be
+construed as a feature, and you shouldn't depend on it.)
+
+Almost.
+
+When an interpreter thread finally shuts down (usually when your program
+exits), then a rather costly but complete mark-and-sweep style of garbage
+collection is performed, and everything allocated by that thread gets
+destroyed. This is essential to support Perl as an embedded or a
+multithreadable language. For example, this program demonstrates Perl's
+two-phased garbage collection:
+
+ #!/usr/bin/perl
+ package Subtle;
+
+ sub new {
+ my $test;
+ $test = \$test;
+ warn "CREATING " . \$test;
+ return bless \$test;
+ }
+
+ sub DESTROY {
+ my $self = shift;
+ warn "DESTROYING $self";
+ }
+
+ package main;
+
+ warn "starting program";
+ {
+ my $a = Subtle->new;
+ my $b = Subtle->new;
+ $$a = 0; # break selfref
+ warn "leaving block";
+ }
+
+ warn "just exited block";
+ warn "time to die...";
+ exit;
+
+When run as F</tmp/test>, the following output is produced:
+
+ starting program at /tmp/test line 18.
+ CREATING SCALAR(0x8e5b8) at /tmp/test line 7.
+ CREATING SCALAR(0x8e57c) at /tmp/test line 7.
+ leaving block at /tmp/test line 23.
+ DESTROYING Subtle=SCALAR(0x8e5b8) at /tmp/test line 13.
+ just exited block at /tmp/test line 26.
+ time to die... at /tmp/test line 27.
+ DESTROYING Subtle=SCALAR(0x8e57c) during global destruction.
+
+Notice that "global destruction" bit there? That's the thread
+garbage collector reaching the unreachable.
+
+Objects are always destructed, even when regular refs aren't and in fact
+are destructed in a separate pass before ordinary refs just to try to
+prevent object destructors from using refs that have been themselves
+destructed. Plain refs are only garbage collected if the destruct level
+is greater than 0. You can test the higher levels of global destruction
+by setting the PERL_DESTRUCT_LEVEL environment variable, presuming
+C<-DDEBUGGING> was enabled during perl build time.
+
+A more complete garbage collection strategy will be implemented
+at a future date.
+
=head1 SEE ALSO
-You should also check out L<perlbot> for other object tricks, traps, and tips.
+You should also check out L<perlbot> for other object tricks, traps, and tips,
+as well as L<perlmod> for some style guides on constructing both modules
+and classes.
In the following sections, these operators are covered in precedence order.
-=head1 DESCRIPTIONS
+=head1 DESCRIPTION
=head2 Terms and List Operators (Leftward)
=head2 Exponentiation
Binary "**" is the exponentiation operator. Note that it binds even more
-tightly than unary minus, so -2**4 is -(2**4), not (-2)**4.
+tightly than unary minus, so -2**4 is -(2**4), not (-2)**4. (This is
+implemented using C's pow(3) function, which actually works on doubles
+internally.)
=head2 Symbolic Unary Operators
=head2 Binding Operators
-Binary "=~" binds an expression to a pattern match.
-Certain operations search or modify the string $_ by default. This
-operator makes that kind of operation work on some other string. The
-right argument is a search pattern, substitution, or translation. The
-left argument is what is supposed to be searched, substituted, or
-translated instead of the default $_. The return value indicates the
-success of the operation. (If the right argument is an expression
-rather than a search pattern, substitution, or translation, it is
-interpreted as a search pattern at run time. This is less efficient
-than an explicit search, since the pattern must be compiled every time
-the expression is evaluated--unless you've used C</o>.)
+Binary "=~" binds an expression to a pattern match. Certain operations
+search or modify the string $_ by default. This operator makes that kind
+of operation work on some other string. The right argument is a search
+pattern, substitution, or translation. The left argument is what is
+supposed to be searched, substituted, or translated instead of the default
+$_. The return value indicates the success of the operation. (If the
+right argument is an expression rather than a search pattern,
+substitution, or translation, it is interpreted as a search pattern at run
+time. This is less efficient than an explicit search, since the pattern
+must be compiled every time the expression is evaluated--unless you've
+used C</o>.)
Binary "!~" is just like "=~" except the return value is negated in
the logical sense.
Ternary "?:" is the conditional operator, just as in C. It works much
like an if-then-else. If the argument before the ? is true, the
argument before the : is returned, otherwise the argument after the :
-is returned. Scalar or list context propagates downward into the 2nd
-or 3rd argument, whichever is selected. The operator may be assigned
-to if both the 2nd and 3rd arguments are legal lvalues (meaning that you
-can assign to them):
+is returned. For example:
+
+ printf "I have %d dog%s.\n", $n,
+ ($n == 1) ? '' : "s";
+
+Scalar or list context propagates downward into the 2nd
+or 3rd argument, whichever is selected.
+
+ $a = $ok ? $b : $c; # get a scalar
+ @a = $ok ? @b : @c; # get an array
+ $a = $ok ? @b : @c; # oops, that's just a count!
+
+The operator may be assigned to if both the 2nd and 3rd arguments are
+legal lvalues (meaning that you can assign to them):
($a_or_b ? $a : $b) = $c;
-Note that this is not guaranteed to contribute to the readability of
-your program.
+This is not necessarily guaranteed to contribute to the readability of your program.
=head2 Assignment Operators
both its arguments into the list.
The => digraph is mostly just a synonym for the comma operator. It's useful for
-documenting arguments that come in pairs. As of 5.001, it also forces
+documenting arguments that come in pairs. As of release 5.001, it also forces
any word to the left of it to be interpreted as a string.
=head2 List Operators (Rightward)
s{}{} Substitution yes
tr{}{} Translation no
-For constructs that do interpolation, variables beginning with "C<$> or "C<@>"
+For constructs that do interpolation, variables beginning with "C<$>" or "C<@>"
are interpolated, as are the following sequences:
\t tab
do I<NOT> interpolate within double quotes, nor do single quotes impede
evaluation of variables when used within double quotes.
+=head2 Regexp Quotelike Operators
+
+Here are the quotelike operators that apply to pattern
+matching and related activities.
+
=over 8
=item ?PATTERN?
data--newlines remain newlines. Unlike in any of the shells, single
quotes do not hide variable names in the command from interpretation.
To pass a $ through to the shell you need to hide it with a backslash.
-The generalized form of backticks is C<qx//>.
+The generalized form of backticks is C<qx//>. (Because backticks
+always undergo shell expansion as well, see L<perlsec> for
+security concerns.)
Evaluating a filehandle in angle brackets yields the next line from
that file (newline included, so it's never false until end of file, at
filehandles C<stdin>, C<stdout> and C<stderr> will also work except in
packages, where they would be interpreted as local identifiers rather
than global.) Additional filehandles may be created with the open()
-function.
+function. See L<perlfunc/open()> for details on this.
If a <FILEHANDLE> is used in a context that is looking for a list, a
list consisting of all the input lines is returned, one line per list
If the string inside the angle brackets is a reference to a scalar
variable (e.g. <$foo>), then that variable contains the name of the
-filehandle to input from.
+filehandle to input from, or a reference to the same. For example:
+
+ $fh = \*STDIN;
+ $line = <$fh>;
-If the string inside angle brackets is not a filehandle, it is interpreted
+If the string inside angle brackets is not a filehandle or a scalar
+variable containing a filehandle name or reference, then it is interpreted
as a filename pattern to be globbed, and either a list of filenames or the
next filename in the list is returned, depending on context. One level of
$ interpretation is done first, but you can't say C<E<lt>$fooE<gt>>
-=head1 NAME
+=head1 NAME
-perlovl - perl overloading semantics
+perlovl - overload perl mathematical functions [superseded]
-=head1 SYNOPSIS
+=head1
- package SomeThing;
+This man page has been superseded by L<overload>.
- %OVERLOAD = (
- '+' => \&myadd,
- '-' => \&mysub,
- # etc
- );
- ...
-
- package main;
- $a = new SomeThing 57;
- $b=5+$a;
-
-=head1 CAVEAT SCRIPTOR
-
-Overloading of operators is a subject not to be taken lightly.
-Neither its precise implementation, syntax, nor semantics are
-100% endorsed by Larry Wall. So any of these may be changed
-at some point in the future.
-
-=head1 DESCRIPTION
-
-=head2 Declaration of overloaded functions
-
- package Number;
- %OVERLOAD = (
- "+" => \&add,
- "*=" => "muas"
- );
-
-declares function Number::add() for addition, and method muas() in
-the "class" C<Number> (or one of its base classes)
-for the assignment form C<*=> of multiplication. Legal values of this
-hash array are values legal inside C<&{ ... }> call, so the name of a
-subroutine, a reference to a subroutine, or an anonymous subroutine
-will all work.
-
-The subroutine C<$OVERLOAD{"+"}> will be called to execute C<$a+$b> if $a
-is a reference to an object blessed into the package C<Number>, or $a is
-not an object from a package with defined mathemagic addition, but $b is a
-reference to a C<Number>. It can be called also in other situations, like
-C<$a+=7>, or C<$a++>. See L<MAGIC AUTOGENERATION>. (Mathemagical
-methods refer to methods triggered by an overloaded mathematical
-operator.)
-
-=head2 Calling Conventions for Binary Operations
-
-The functions in C<values %OVERLOAD> are called with three (in one
-particular case with four, see L<Last Resort>) arguments. If the
-corresponding operation is binary, then the first two arguments are the
-two arguments of the operation. However, due to general object calling
-conventions, the first argument should be always an object in the package,
-so in the situation of C<7+$a>, the order of arguments is interchanged.
-Most probably it does not matter for implementation of the addition
-method, but whether the arguments are reversed is vital for the
-subtraction method. The subroutine can query this information by
-examining the third argument, which can take three different values:
-
-=over 7
-
-=item FALSE
-
-the order of arguments is as in the current operation.
-
-=item TRUE
-
-the arguments are reversed.
-
-=item C<undef>
-
-the current operation is an assignment variant (as in
-C<$a+=7>), but the usual function is called instead. This additional
-information can be used to generate some optimizations.
-
-=back
-
-=head2 Calling Conventions for Unary Operations
-
-Unary operation are considered binary operations with the second
-argument being C<undef>. Thus C<$OVERLOAD{"++"}> is called with
-arguments C<($a,undef,'')> when $a++ is executed.
-
-=head2 Overloadable Operations
-
-The following keys of %OVERLOAD are recognized:
-
-=over 5
-
-=item * I<Arithmetic operations>
-
- "+", "+=", "-", "-=", "*", "*=", "/", "/=", "%", "%=",
- "**", "**=", "<<", "<<=", ">>", ">>=", "x", "x=", ".", ".=",
-
-For these operations a substituted non-assignment variant can be called if
-the assignment variant is not available. Methods for operations "C<+>",
-"C<->", "C<+=>", and "C<-=>" can be called to automatically generate
-increment and decrement methods. The operations "C<->" can be used to
-autogenerate missing methods for unary minus or C<abs>.
-
-=item * I<Comparison operations>
-
- "<", "<=", ">", ">=", "==", "!=", "<=>",
- "lt", "le", "gt", "ge", "eq", "ne", "cmp",
-
-If the corresponding "spaceship" variant is available, it can be
-used to substitute for the missing operation. During C<sort>ing
-arrays, C<cmp> is used to compare values subject to %OVERLOAD.
-
-=item * I<Bit operations>
-
- "&", "^", "|", "&=", "^=", "|=", "neg", "!", "~",
-
-"C<neg>" stands for unary minus. If the method for C<neg> is not
-specified, it can be autogenerated using on the method for subtraction.
-
-=item * I<Increment and decrement>
-
- "++", "--",
-
-If undefined, addition and subtraction methods can be
-used instead. These operations are called both in prefix and
-postfix form.
-
-=item * I<Transcendental functions>
-
- "atan2", "cos", "sin", "exp", "abs", "log", "sqrt",
-
-If C<abs> is unavailable, it can be autogenerated using methods
-for "<" or "<=>" combined with either unary minus or subtraction.
-
-=item * I<Boolean, string and numeric conversion>
-
- "bool", "\"\"", "0+",
-
-If one or two of these operations are unavailable, the remaining ones can
-be used instead. C<bool> is used in the flow control operators
-(like C<while>) and for the ternary "C<?:>" operation. These functions can
-return any arbitrary Perl value. If the corresponding operation for this value
-is overloaded too, that operation will be called again with this value.
-
-=item * I<Special>
-
- "nomethod", "fallback", "=",
-
-see L<SPECIAL KEYS OF %OVERLOAD>.
-
-=back
-
-See L<"Fallback"> for an explanation of when a missing method can be autogenerated.
-
-=head1 SPECIAL KEYS OF %OVERLOAD
-
-Three keys are recognized by Perl that are not covered by the above
-description.
-
-=head2 Last Resort
-
-C<$OVERLOAD{"nomethod"}> is a reference to a function of four parameters.
-If defined, it is called when the overloading mechanism cannot find a
-method for some operation. The first three arguments of this function
-coincide with arguments for the corresponding method if it were found, the
-fourth argument is the key of %OVERLOAD corresponding to the missing
-method. If several methods are tried, the last one is used. Say, C<1-$a>
-can be equivalent to
-
- &{ $Pack::OVERLOAD{"nomethod"} }($a,1,1,"-").
-
-If some operation cannot be resolved, and there is no
-C<$OVERLOAD{"nomethod"}>, then an exception will be raised
-via die() -- unless C<$OVERLOAD{"fallback"}> is true.
-
-=head2 Fallback
-
-C<$OVERLOAD{"fallback"}> governs what to do if a method for a particular
-operation is not found. Three different cases are possible depending on
-value of C<$OVERLOAD{"fallback"}>:
-
-=over 16
-
-=item * C<undef>
-
-Perl tries to use a
-substituted method (see L<MAGIC AUTOGENERATION>). If this fails, it
-then tries to calls C<$OVERLOAD{"nomethod"}>; if missing, an exception
-will be raised.
-
-=item * TRUE
-
-The same as for the C<undef> value, but no exception is raised. Instead,
-it silently reverts to what it would have done were there no %OVERLOAD is
-present.
-
-=item * defined, but FALSE
-
-No autogeneration is tried. Perl tries to call
-C<$OVERLOAD{"nomethod"}>, and if this is missing, raises an exception.
-
-=back
-
-=head2 Copy Constructor
-
-C<$OVERLOAD{"="}> is a reference to a function with three arguments,
-i.e., it looks like a usual value of %OVERLOAD. This operation
-is called in the situations when a mutator is applied to a reference
-that shares its object with some other reference, such as
-
- $a=$b;
- $a++;
-
-To make this change to $a and not to change $b, a freshly made copy of
-C<$$a> is made, and $a is assigned a reference to this object. This
-operation is executed during C<$a++>, (so before this C<$$a> coincides
-with C<$$b>), and only if C<++> is expressed via C<$OPERATOR{'++'}> or
-C<$OPERATOR{'+='}>. Note that if this operation is expressed via 'C<+>',
-i.e., as
-
- $a=$b;
- $a=$a+1;
-
-then C<$$a> and C<$$b> do not appear as lvalues.
-
-If the copy constructor is required during execution of some mutator, but
-C<$OPERATOR{'='}> is missing, it can be autogenerated as a string
-copy if an object of
-the package is a plain scal