PERL FAQ
Archive-name: perl-faq/part0
Version: $Id: perl-intro,v 2.2 1994/11/07 18:05:12 spp Exp spp $
Posting-Frequency: bi-weekly
Archive-name: perl-faq/part1
Version: $Id: part1,v 2.3 1994/11/07 18:05:23 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to general information and availability
questions. The following questions are answered in this posting:
1.1) What is Perl?
Perl is a compiled scripting language written by Larry Wall*.
Here's the beginning of the description from the perl(1) man page:
Perl is an interpreted language optimized for scanning arbi-
trary text files, extracting information from those text
files, and printing reports based on that information. It's
also a good language for many system management tasks. The
language is intended to be practical (easy to use, effi-
cient, complete) rather than beautiful (tiny, elegant,
minimal). It combines (in the author's opinion, anyway)
some of the best features of C, sed, awk, and sh, so people
familiar with those languages should have little difficulty
with it. (Language historians will also note some vestiges
of csh, Pascal, and even BASIC-PLUS.) Expression syntax
corresponds quite closely to C expression syntax. Unlike
most Unix utilities, perl does not arbitrarily limit the
size of your data--if you've got the memory, perl can slurp
in your whole file as a single string. Recursion is of
unlimited depth. And the hash tables used by associative
arrays grow as necessary to prevent degraded performance.
Perl uses sophisticated pattern matching techniques to scan
large amounts of data very quickly. Although optimized for
scanning text, perl can also deal with binary data, and can
make dbm files look like associative arrays (where dbm is
available). Setuid perl scripts are safer than C programs
through a dataflow tracing mechanism which prevents many
stupid security holes. If you have a problem that would
ordinarily use sed or awk or sh, but it exceeds their capa-
bilities or must run a little faster, and you don't want to
write the silly thing in C, then perl may be for you. There
are also translators to turn your sed and awk scripts into
perl scripts. OK, enough hype.
1.2) What are perl4 and perl5, are there any differences?
Perl4 and perl5 are different versions of the language. Perl4 was
the
previous release, and perl5 is "Perl: The Next Generation."
Perl5 is, essentially, a complete rewrite of the perl source code
from the ground up. It has been modularized, object oriented,
tweaked, trimmed, and optimized until it almost doesn't look like
the old code. However, the interface is mostly the same, and
compatibility with previous releases is very high.
1.3) What features does perl5 provide over perl4?
If you get the newest source (from any of the main FTP sites), you
will
find a directory full of man pages (possibly to be installed as
section
1p and 3pm) that discuss the differences, new features, old
incompatibilies and much more. Here, however, are some highlights
as
to the new feature and old incompatibilites.
* Enhanced Usability: Perl code can now be written in a much more
legible style. Regular expressions have been enhanced to allow
minimal matches, conditionals, and much more. Cryptic variable
names (although still supported) have been aliased to new
nmemonics, using the "English" module, allowing old scripts to
run
and new scripts to be readable. Error messages and optional
warnings are more informative and will catch many common
mistakes.
See the perldiag(1) man page, which contains pithy prose from
Larry
Wall* on each and every possible muttering perl might spout at
you.
* Simplified Grammar: The new yacc grammar is one half the size
of
the old one. Many of the arbitrary grammer rules have been
regularized. The number of reserved words has been cut by 2/3.
* Lexical Scoping: Perl variables may now be declared within a
lexical scope, similar to C's "auto" variables. This is a
great improvement on efficiency and contributes to better
privacy. See the my() entry in perlfunc(1).
* Arbitrarily nested data structures: Full fledged
multidimensional
arrays. Any scalar value, including an array element, may now
contain a reference to any other variable or subroutine.
Easily created anonymous variables and subroutines. See
perlref(1).
* Modularity and Reusability: The Perl library is now defined in
terms of modules which can be easily shared among various
packages. Packages can import any or all of a module's
published interface. See perlmod(1), perlsub(1), and
Exporter(3pm).
* Object-oriented programming: A package can function as a class.
Dynamic multiple inheritance and virtual methods are supported
in a straight-forward manner with little new syntax. Filehandles
are now treated as objects. See perlobj(1), perlmod(1), and
FileHandle(3pm).
* Embeddible and Extensible: Perl can be easily embedded in C/C++
approlications, and can either call or be called by your
routines through a documented interface. The XS preprocessor
is provided to make it easy to glue your C/C++ routines into
Perl. Dynamic loading of modules is supported. See perlapi(1),
perlcall(1), and DynaLoader(3pm).
* POSIX compliant: A major new module is the POSIX module, which
provides access to all available POSIX routines and definitions.
Seee POSIX(3pm).
* Package constructors and destructors: The new BEGIN and END
blocks
provide means to capture control as a package is being compiled
and
after the program exits. As a degenerate case, they work just
like
awk's BEGIN and END when you use the -p or -n switches. See
perlmod(1).
* Multiple simultaneous DBM implementations: A perl program now
has
access to DBM, NDBM, SDBM, GDBM and Berkeley DB files in the same
script. The dbmopen interface has been generalized to allow any
variable to be tied to an object class which defines its access
methods. tie/untie now preferable to dbmopen/dbmclose. See the
tie() entry in perlfunc(1) and the DB_File(3pm) man pages.
* Subroutine definitions may now be autoloaded: The AUTOLOAD
mechanism
allows any arbitrary semantics to undefined subroutine calls.
See
the section on Autoloading in the perlsub(1) manpage.
* Regular Expression Enhancements: Qualifiers may be followed by
a "?"
to signify that they should be non-greedy. A "?" directly after
an opening paren indicates non backreference grouping and the next
character determines the purpose of the match (?:a|b|c) will match
any of a b or c without producing a backreference, (?=stuff) does
a non-eating look ahead to assure that the next thing is stuff,
(?!nonsense) looks ahead to assure that the next thing must not
be "nonsense". Embedded whitespace and comments for readability.
A consistent extensibility mechanism has been added that is
upwardly compatible with all old regexps. Variables may now be
interpoled literally into a pattern with \Q or the quotemeta
fuction, which works like \U but backwhacks non-alphanumerics.
New m and s "flags" for pattern matching force multi- or
single-line matching. The "s" makes "." match "\n". \A and
\Z anchor matches to the beginning and end of a string and ignore
multiline semantics. \G matches where the previous m//g or s///g
left off.
* The -w (warnings) switch is much more informative.
* References and Objects (see t/op/ref.t) for examples.
* => is a synonum for comma and helps group paired arguments, such
as initializers for associative arrays and named arguments to
subroutines.
* All functions, even predeclared subroutines, are treated as list
operators or unary operators. Parens are optional.
* Flattened interpreter: Compare perl4's eval.c with perl5's
pp.c.
Compare perl4's 900 line interpreter look with perl5's one line.
* eval is now treated like a subroutine call, meaning (among other
things) you can return from it.
* format value lists may be spread over multiple lines with a do
{}
block.
* flags on the #! line are interpreted even if the script wasn't
invoked directly.
* ?: is now an lvalue.
* list context now propogates to the right side of && and ||, and
as the 2nd and 3rd arguments of ?:
* preferred package delimeter now :: rather than '.
* new "and" and "or" operators, like && and || but with a lower
precedence than comma, so they work better with list operators.
* New functions abs(), chr(), uc(), ucfirst(), lc(), and lcfirst()
* require(number) checks to see that the version is at least that
version
* qw//, which is equivalent to split(' ', q//)
* assignment of a reference to a glob replaces the single element
of the glob corresponding to the reference type:
*foo = \$bar, * foo = \&bletch;
* filehandle methods are supported:
output_autoflush STDOUT 1;
* Autoload stubs can now call the replacement subroutine with
goto &realsub.
* Subroutines can be defined lazily in any package by declaring
an AUTOLOAD routine, which will be called if a non-existant
subroutine is called in that package.
* "use" and "no" subsume many feautres. "use Module LIST" is
short for "BEGIN { require Module; import Module LIST }"
"no" is identical, except that it calls "unimport" instead.
"use integer" and variations of "use strict [vars,refs,subs]"
were implemented through new modules.
(Thanks to Tom Christiansen* for this section)
1.4) Where can I get docs on perl5?
The complete perl documentation is available with the Perl
distribution, or can be accessed from the following sites.
Note that the PerlDoc ps file is 240 pages long!!
http://www.metronet.com/0/perlinfo/perl5/manual/perl.html
ftp://ftp.uu.net/languages/perl/PerlDoc.ps.gz
ftp://prep.ai.mit.edu/pub/gnu/PerlDoc.ps.gz
ftp://ftp.cbi.tamucc.edu/pub/duff/Perl/PerlDoc.ps.gz
ftp://www.metronet.com/pub/perlinfo/perl5/manual/PerlDoc.ps.gz
http://web.nexor.co.uk/perl/perl.html (Europe)
ftp://ftp.zrz.tu-berlin.de/pub/unix/perl/PerlDoc.ps.gz
(Europe)
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/PerlDoc.ps.gz
(Europe)
ftp://sungear.mame.mu.oz.au/pub/perl/doc/PerlDoc.ps.gz (Oz)
1.5) Will perl5 break my perl4 scripts?
In general, no. However, certain bad old practices have become
highly
frowned upon. The following are the most important of the known
incompatibilies between perl4 and perl5. See perltrap(1) for more
details.
* "@" ***ALWAYS*** interpolate in double quoted strings. Non-
array
"@"s must be escaped:
Mail("foo@bar.com") needs to be
Mail("foo\@bar.com");
The compiler catches this.
* "open FILE || die" needs to be "open(FILE) || die". The
compiler
forgives you for this, but won't stop complaining until you fix
it.
* Barewords are no longer (necessarily) strings: they will
actually
call the function (if it existed when that code was compiled)
instead of returning a string of that value. Check your
signal handlers. The 'use strict subs' pragma (see strict(3pm))
will help you with this.
* "shift @x + 20" needs to be "shift(@x) + 20" because of
precedence,
and likewise "$y = scalar keys %foo + 30" needs to be instead
"$y = scalar keys(%foo) + 30".
* The internal symbol table is called %{PACKAGE::} for any given
package. It used to be %{_PACKAGE}.
* You may no longer (attempt to) write to read-only variables,
like $1,
or assign to a substr() past the end of a string.
* Various deprecated practices elicit warning messages.
1.6) When will Perl stabilize?
When asked at what point the Perl code would be frozen, Larry answere:
Part of the redesign of Perl is to *allow* us to more or less
freeze
the language itself. It won't totally freeze, of course, but I
think
the rate of change of the core of the language is asymptotically
approaching 0. In fact, as time goes on, now that we have an
official
extension mechanism, some of the things that are currently in the
core
of the language may move out (transparently) as extensions. This
has
already happened to dbmopen().
I've also been continuously reminding myself of what Henry Spencer
calls "second system syndrome", in which everything under the sun
gets
added, resulting in a colossal kludge, like OS 360. You'll find
that
the new features in Perl 5 are all pretty minimalistic. The
object-oriented features in particular added only one new piece of
syntax, a C++-style method call.
: The whole idea
: Perl is to be a fast text-processing, system-maintenance, zero-
startup
: time language. If it gets to be so large and complicated that it
isn't
: fast-running and easy to use, it won't be to anyone's benefit.
My motto from the start has been, "If it ain't broke, don't fix
it."
I've been trying very hard not to remove those features from Perl
that
make it what it is. At the same time, a lot of streamlining has
gone
into the syntax. The new yacc file is about half the size of the
old
one, and the number of official reserved words has been cut by
2/3.
All built-in functions have been unified (dualified?) as either
list
operators or unary operators.
: I really like a lot of the features in Perl, but in order for
Perl to
: be useful on a long term basis, those features have to stay put.
I
: bought the Camel book less than a year ago and it sounds like
within
: another year it will be obsolete.
The parts of Perl that the Camel book covers have not changed all
that
much. Most old scripts still run. Many scripts from Perl version
1.0
still run. We'll certainly be revising the Camel, but the new man
pages are split up such that it's pretty easy to ferret out the
new
info when you want it.
We did break a few misfeatures in going to Perl 5. It seemed like
the
first and last chance to do so. There's a list of the
incompatibilities in the documentation.
: Not only is it a lot of work to recompile Perl
: on 20+ machines periodically, but it's hard to write scripts
that are
: useful in the long term if the guts of the language keep
changing.
: (And if I keep having to buy new books. I keep hearing about new
: features of Perl 5 that aren't documented in any of the perl 5
: documentation that *I* can find.)
I think you'll find a lot of folks who think that 4.036 has been a
pretty stable platform.
Perl 5 is a special case. I've been working on it for years.
(This is
part of the reason 4.036 has been so stable!) There are many
changes,
most of them for the better, I hope. I don't expect the
transition to
be without pain. But that's why I stuck numbered versions out in
your
bin directory, so that you can upgrade piecemeal if you like. And
that's why I made the -w switch warn about many of the
incompatibilities.
And overriding all that, I've tried to keep it so that you don't
have
to know much about the new stuff to use the old stuff. You can
upgrade
your *knowledge* piecemeal too.
The extension mechanism is designed to take over most of the
evolutionary role from now on. And it's set up so that, if you
don't
have a particular extension, you know it right up at the front.
: Are there any plans to write a Perl compiler? While interpreted
Perl
: is great for many applications, it would also be cool to be able
to
: precompile many scripts. (Yes, I know you can undump things, but
: undump isn't provided with Perl and I haven't found a copy.) The
: creation of a perl library and dynamically-loadable modules
seems
: like a step in that direction.
Yes, part of the design of Perl 5 was to make it *possible* to
write a
compiler for it. It could even be done as an extension module, I
suppose. Anyone looking for a master's thesis topic?
In summary, almost every concern that you might think of has
already
been (at least) thought about. In a perfect world, every concern
could be addressed perfectly. But in this world we just have to
slog
through.
1.7) What's the difference between "perl" and "Perl"?
32! [ ord('p') - ord('P') ] (Shouldn't that be 42, the Answer to
the
Great Question of Life, the Universe, and Everything? ;)
Larry now uses "Perl" to signify the language proper and "perl"
the
implementation of it, i.e. the current interpreter. Hence Tom's
quip that "Nothing but perl can parse Perl."
On the other hand, the aesthetic value of casewise parallelism in
"awk", "sed", and "perl" as much require the lower-case version as
"C",
"Pascal", and "Perl" require the upper-case version. It's also
easier
to type "Perl" in typeset print than to be constantly switching in
Courier. :-)
In other words, it doesn't matter much, especially if all you're
doing
is hearing someone talk about the language; case is hard to
distinguish
aurally.
1.8) Is it a perl program or a perl script?
It depends on whether you are talking about the perl binary or
something that you wrote using perl. And, actually, even this
isn't
necessarily true.
"Standard" UNIX terminology is (roughly) this: programs are
compiled
into machine code once and run multiple times, scripts are
translated
(by a program) each time they are used. However, some say that a
program is anything written which is executed on a computer
system.
Larry considers it a program if it is set in stone and you can't
change
it, whereas if you can go in and hack at it, it's a script. Of
course,
if you have the source code, that makes just about anything a
script. ;)
In general, it probably doesn't really matter. The terms are used
interchangeably. If you particularly like one or the other, use
it. If
you want to call yourself a perl programmer, call them programs.
If
you want to call yourself a perl scripter, call them scripts.
Randal*
and I (at least) will call them hacks. (See question 2.10 ;)
1.9) Is perl difficult to learn?
Not at all. Many people find Perl extremely easy to learn. There
are
at least three main reasons for this.
The first reason is that most of Perl has been derived from
standard
utilities, tools, and languages that you are (probably) already
familiar with. If you have any knowledge of the C programming
language
and standard C library, the Unix Shell, sed and awk, Perl should
be
simple and fun for you to learn.
The second reason that Perl is easy to learn is that you only have
to
know a very small subset of Perl to be able to get useful results.
In
fact, once you can master
#!/usr/local/bin/perl
úÿ
print "Hello, world\n";
you can start writing Perl scripts. In fact, you will probably
never
have to (or be able to) know everything about Perl. As you feel
the
need or desire to use more sophisticated features (such as C
structures
or networking), you can learn these as you go. The learning curve
for
Perl is not a steep one, especially if you have the headstart of
having
a background in UNIX. Rather, its learning curve is gentle and
gradual, but it *is* admittedly rather long.
The third reason is that you can get immediate results from your
scripts. Unlike a normal compiled language (like C or Pascal, for
example), you don't have to continually recompile your program
every
time you change one little thing. Perl allows you to experiment
and
test/debug quickly and easily. This ease of experimentation
flattens
the learning curve even more.
If you don't know C or UNIX at all, it'll be a steeper learning
curve,
but what you then learn from Perl will carry over into other
areas,
like using the C library, UNIX system calls, regular expressions,
and
associative arrays, just to name a few. To know Perl is to know
UNIX,
and vice versa.
1.10) Should I program everything in Perl?
Most definitely. In fact, you should delete the binaries for sed,
awk,
cc, gcc, grep, rm, ls, cat... well, just delete your /bin
directory.
But seriously, of course you shouldn't. As with any job, you
should
use the appropriate tool for the task at hand. Just because a
hammer
will put screws into a piece of board, you probably don't want to
do
that.
While it's true that the answer to the question "Can I do (some
arbitrary task) in Perl?" is almost always "yes", that doesn't
mean
this is necessarily a good thing to do. For many people, Perl
serves
as a great replacement for shell programming. For a few people,
it
also serves as a replacement for most of what they'd do in C. But
for
some things, Perl just isn't the optimal choice, such as tasks
requiring very complex data structures.
1.11) How does Perl compare with other scripting languages, like Tcl,
Python
or REXX?
REXX is an interpreted programming language first seen on IBM
systems.
Python is an interpreted programming language by Guido van
Rossum*.
TCL is John Ousterhout*'s embeddable command language, designed
just
for embedded command extensions, but lately used for larger
applications. TCL's most intriguing feature for many people is
the
tcl/tk toolset that allows for interpreted X-based tools. Others
use
it for its "expect" extension.
To avoid any flamage, if you really want to know the answer to
this
question, probably the best thing to do is try to write equivalent
code to do a set of tasks. All three have their own newsgroups in
which you can learn about (but hopefully not argue about) these
languages.
To find out more about these or other languages, you might also
check
out David Muir Sharnoff*'s posting "Catalog of Compilers,
Interpreters,
and Other Language Tools" which he posts to comp.lang.misc,
comp.sources.d, comp.archives.admin, and news.answers newsgroups.
It's
a comprehensive treatment of many different languages. (Caveat
lector:
he considers Perl's syntax "unappealing".)
1.12) How can I get Perl over the Internet?
Perl is available from any comp.sources.misc archive. You can use
an
archie server (see the alt.sources FAQ in news.answers) to find
these
if you want.
Volume Issues Patchlevel and Notes
------ ------ ------------------------------------------------
18 19-54 Patchlevel 3, Initial posting.
20 56-62 Patches 4-10
Since 1993, a number of archives have sprung up specifically for
Perl
and Perl related items. Larry maintains the official distribution
site (for both perl4.036 and perl5) at netlabs. Probably the
largest
archive is at the University of Florida. In order of probability
these
sites will have the sources.
Site IP Directory and notes
----------- ------- -------------------------------
North America:
ftp.netlabs.com 192.94.48.152 /pub/outgoing/perl[VERSION]/
ftp.cis.ufl.edu 128.227.100.198 /pub/perl/src/[VERSION]/
prep.ai.mit.edu 18.71.0.38 /pub/gnu/perl5.000.tar.gz
ftp.uu.net 192.48.96.9 /languages/perl/perl5.000.tar.gz
ftp.khoros.unm.edu 198.59.155.28 /pub/perl/perl5.000.tar.gz
ftp.cbi.tamucc.edu 165.95.1.3
/pub/duff/Perl/perl5.000.tar.gz
ftp.metronet.com 192.245.137.1 /pub/perl/sources/
genetics.upenn.edu 128.91.200.37 /perl5/perl5_000.zip
Europe:
ftp.cs.ruu.nl 131.211.80.17
/pub/PERL/perl5.0/perl5.000.tar.gz
ftp.funet.fi 128.214.248.6
/pub/languages/perl/ports/perl5/perl5.000.tar.gz
ftp.zrz.tu-berlin.de 130.149.4.40
/pub/unix/perl/perl5.000.tar.gz
src.doc.ic.ac.uk 146.169.17.5
/packages/perl5/perl5.000.tar.gz
Australia:
sungear.mame.mu.oz.au 128.250.209.2
/pub/perl/src/5.0/perl5.000.tar.gz
If there is a site in Asia or Japan, please tell us about it.
Thanks!
You can also retrieve perl via non-ftp methods:
http: //src.doc.ic.ac.uk/packages/perl5/perl5.000.tar.gz
gopher:
//src.doc.ic.ac.uk/0/packages/perl5/perl5.000.tar.gz
1.13) How can I get Perl via Email?
The following is a list of known ftpmail sites. Please attempt to
use
the site closest to you with the ftp archive closest to it. Many
of
these sites already have perl on them. For information on how to
use
one of these sites, send email containing the word "help" to the
address.
United States:
Massachusetts: ftpmail@decwrl.dec.com
New Jersey: bitftp@pucc.princeton.edu
North Carolina: ftpmail@sunsite.unc.edu
Europe/UK:
Germany: ftpmail@ftp.uni-stuttgart.de
bitftp@vx.gmd.de
UK: ftpmail@doc.ic.ac.uk
Australia: ftpmail@cs.uow.edu.au
Henk P Penning* suggests that if you are in Europe you should try
the
following (if you are in Germany or the UK, you should probably
use one
of the servers listed above):
Email: Send a message to 'mail-server@cs.ruu.nl' containing:
begin
path your_email_address
send help
send PERL/INDEX
end
The path-line may be omitted if your message contains a normal
From:-line. You will receive a help-file and an index of the
directory that contains the Perl stuff.
If all else fails, mail to Larry usually suffices.
1.14) How can I get Perl via UUCP?
There currently is no way of getting Perl via UUCP. If anyone
knows of
a way, please contact me. The OSU site has discontinued the
service.
1.15) Are there other ways of getting perl?
Another possibility is to use UUNET, although they charge you for
it.
You have been duly warned. Here's the advertisement:
Anonymous Access to UUNET's Source Archives
1-900-GOT-SRCS
UUNET now provides access to its extensive collection of UNIX
related sources to non- subscribers. By calling 1-900-468-7727
and using the login "uucp" with no password, anyone may uucp any
of UUNET's on line source collection. Callers will be charged 40
cents per minute. The charges will appear on their next tele-
phone bill.
The file uunet!/info/help contains instructions. The file
uunet!/index//ls-lR.Z contains a complete list of the files
available and is updated daily. Files ending in Z need to be
uncompressed before being used. The file uunet!~/compress.tar is
a tar archive containing the C sources for the uncompress program.
This service provides a cost effective way of obtaining
current releases of sources without having to maintain accounts
with UUNET or some other service. All modems connected to the
900 number are Telebit T2500 modems. These modems support all
standard modem speeds including PEP, V.32 (9600), V.22bis (2400),
Bell 212a (1200), and Bell 103 (300). Using PEP or V.32, a 1.5
megabyte file such as the GNU C compiler would cost $10 in con-
nect charges. The entire 55 megabyte X Window system V11 R4
would cost only $370 in connect time. These costs are less than
the official tape distribution fees and they are available now
via modem.
UUNET Communications Services
3110 Fairview Park Drive, Suite 570
Falls Church, VA 22042
+1 703 876 5050 (voice)
+1 703 876 5059 (fax)
info@uunet.uu.net
1.16) Has perl been ported to machine FOO?
Perl runs on virtually all Unix machines simply by following the
hints
file and instructions in the Configure script. This auto-
configuration
script allows Perl to compile on a wide variety of platforms by
modifying the machine specific parts of the code. For most Unix
systems, or VMS systems for v5 perl, no porting is required. Try
to
compile Perl on your machine. If you have problems, examine the
README
file carefully. If all else fails, send a message to
comp.lang.perl
and crosspost to comp.sys.[whatever], there's probably someone out
there that has already solved your problem and will be able to
help you
out.
Perl has been ported to many non-Unix systems, although currently
there
are no v5 ports. All of the following are mirrored at
ftp.cis.ufl.edu:/pub/perl/src/[OS]/. The following are the
(known)
official distribution points. Please contact the porters directly
(when possible) in case of questions on these ports.
* MS-DOS binaries and source are available at ftp.ee.umanitoba.ca
[130.179.8.47] in /pub/msdos/perl
There are currently half a dozen different ports for MS-DOS.
BigPerl4 (v3) is perl4.036 compiled with the Watcom C/386
compiler (32-bit, flat-memory model C compiler) with the
following features:
* Up to 32MB of memory can be used.
* Supports virtual memory.
* Works under Windows 3.1 (however, a second copy of perl cannot
be spawned under Windows).
* The perl debugger can be used.
* Contains GDBM support.
* Windows/NT binaries are available from ftp.cis.ufl.edu. Does
anyone know the official distribution point? I got these from
archive.cis.ohio-state.edu quite awhile back.
* Machintosh binaries and source are available from nic.switch.ch
[130.59.1.40] in /software/mac/perl.
Version 4.1.3 is perl4.036 compiled with the MPW C compiler
* Mac_Perl_413_src.sit.bin Sources
* Mac_Perl_413_tool.sit.bin MPW Tool
* Mac_Perl_413_appl.sit.bin Standalone Application
There is a mailing list for discussing Macintosh Perl. Contact
"mpw-perl-request@iis.ee.ethz.ch".
Timothy Murphy* also ported a version of perl to the Macintosh
using Think C. It has probably been abandoned in favour of the
MPW port, but is still available at ftp.maths.tcd.ie
[134.266.81.10] in the directory /pub/Mac/perl-4.035/.
* OS/2 sources are also available at ftp.cis.ufl.edu in
/pub/perl/src/os2. This appears to have been abandoned and added
to the official distribution. See the directory os2 in the perl5
sources.
* VMS systems should be able to build directly from the standard
distribution.
1.17) How do I get Perl to compile on Solaris?
The following directions are for perl, version 4. Perl, version
5,
should compile more easily. If not, send mail to The Perl Porters
Mailing List (perl5-porters@isu.edu)
John Lees* reports:
I have built perl on Solaris 2.1, 2.2 beta, and 2.2 FCS. Take
/usr/ucb out of your path and do not use any BSD/UCB libraries.
Only -lsocket, -lnsl, and -lm are needed. You can use the hint for
Solaris 2.0, but the one for 2.1 is wrong. Do not use vfork. Do not
use -I/usr/ucbinclude. The result works fine for me, but of couse
does not support a couple of BSDism's.
Casper H.S. Dik* reports
You must remove all the references to /usr/ucblib AND
/usr/ucbinclude. And ignore the Solaris_2.1 hints. They are
wrong.
The undefining of vfork() probably has to do with the
confusion it
gives to the compilers. If you use cc, you mustn't compile
util.c/tutil.c with -O. I only used the following libs: -lsocket
-lnsl -lm (there is a problem with -lmalloc)
Michael D'Errico* reports:
If you are using Solaris 2.x, the signal handling is broken.
If
you set up a signal handler such as 'ripper' it will be forgotten
after the first time the signal is caught. To fix this, you need
to recompile Perl. Just add '#define signal(x,y) sigset((x),(y))'
after the '#include <signal.h>' directive in each file that it
occurs, then make it again.
1.18) How do I get Perl to compile on a Next?
According to Andreas Koenig*, under NeXTstep 3.2, both perl4.036
and
perl5.000 compile with the supplied hints file.
However, Bill Eldridge* provides this message to help get
perl4.036 on
NeXTstep 3.0 to work:
To get perl to compile on NeXTs, you need to combine the ANSI
and BSD headers:
cd /usr/include
mkdir ansibsd
cd ansibsd
ln -s ../ansi
ln -s ../bsd
Then, follow the configuration instructions for NeXTs,
*replacing*
all mention of -I/usr/include/ansi or -I/usr/include/bsd with
-I/usr/include/ansibsd.
1.19) What extensions are available from Perl and where can I get
them?
Some of the more popular extensions include those for windowing,
graphics, or data base work. See perlmod(1).
Tk (as in tcl/tk, but sans tcl)
ftp://ftp.cis.ufl.edu/pub/perl/src/tkperl/tkperl5a5.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/tkperl5a5.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/tkperl/tkperl5a5.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/tkperl5a5.tar.gz
ftp://black.ox.ac.uk/src/ALPHA/tkperl5a5.tar.gz
Curses (standard C library)
ftp://ftp.ncsu.edu/pub/math/wsetzer/cursperl5a6.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/cursperl5a6.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/cursperl5a6.tar.gz
Msql (SQL)
ftp://ftp.zrz.TU-Berlin.DE/pub/unix/perl/MsqlPerl-a1.tgz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/MsqlPerl-a1.tgz
ftp://ftp.metronet.com/pub/perlinfo/perl5/MsqlPerl5-a1.tgz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/MsqlPerl-a1.tar.gz
Sx (Athena & Xlib)
ftp://ftp.pasteur.fr/pub/Perl/Sx.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/Sx.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/Sx.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/PerlDoc.ps.gz
1.20) What is dbperl and where can I get it?
Many database-oriented extensions to Perl have been written.
Basically, these use the usub mechanism (see the usub/
subdirectory) in
the source distribution) to link in a database library, allowing
embedded calls to Informix, Ingres, Interbase, Oracle and Sybase.
Here are the authors of the various extensions:
What Target DB Who
-------- ----------- -----------------------------------
-----
?Infoperl Informix Kurt Andersen
(kurt@hpsdid.sdd.hp.com)
Ingperl Ingres Tim Bunce (timbo@ig.co.uk) and Ted Lemon
Interperl Interbase Buzz Moschetti (buzz@bear.com)
Isqlperl Informix William Hails, bill@tardis.co.uk
Oraperl Oracle Kevin Stock (kstock@Auspex.com)
Pgperl Postgres Igor Metz (metz@iam.unibe.ch)
*Sqlperl Ingres Ted Lemon (mellon@ncd.com)
Sybperl Sybase Michael Peppler (mpeppler@itf.ch)
Uniperl Unify 5.0 Rick Wargo (rickers@coe.drexel.edu)
? Does this one still exist?
* Sqlperl appears to have been subsumed by Ingperl
Buzz Moschetti* has organized a project to create a higher level
interface to will allow you to write your queries in a database-
independent fashion. If this type of project interests you, send
mail
to <perldb-interest-request@vix.com> and asked to be placed on the
"perldb-interest" mailing lists.
Here's a bit of advertising from Buzz:
Perl is an interpreted language with powerful string, scalar, and
array processing features developed by Larry Wall that "nicely
bridges the functionality gap between sh(1) and C." Since
relational DB operations are typically textually oriented, perl is
particularly well-suited to manage the data flows. The C source
code, which is available free of charge and runs on many platforms,
contains a user-defined function entry point that permits a
developer to extend the basic function set of the language. The
DBperl Group seeks to exploit this capability by creating a
standardized set of perl function extensions (e.g. db_fetch(),
db_attach()) based the SQL model for manipulating a relational DB,
thus providing a portable perl interface to a variety of popular
RDMS engines including Sybase, Oracle, Ingres, Informix, and
Interbase. In theory, any DB engine that implements a dynamic SQL
interpreter in its HLI can be bolted onto the perl front end with
predicatable results, although at this time backends exist only for
the aforementioned five DB engines.
The official archive for DBperl extensions is ftp.demon.co.uk:
/pub/perl/db. It's the home of the evolving DBperl API
Specification.
Here's an extract from the updated README there:
DBI/ The home of the DBI archive. To join the DBI mailing list
send your request to perldb-interest-REQUEST@vix.com
úÿ
DBD/ Database Drivers for the DBI ...
Oracle/ By Tim Bunce (not yet ready!)
Ingres/ By Tim Bunce (not yet started!)
mod/ Other Perl 5 Modules and Extensions ...
Sybperl/ By Michael Peppler, mpeppler@itf.ch
perl4/ Perl 4 extensions (using the usub C interface)
oraperl/ ORACLE 6 & 7 By Kevin Stock (sadly no longer on the
net)
sybperl/ SYBASE 4 By Michael Peppler, mpeppler@itf.ch
ingperl/ INGRES By Tim Bunce timbo@ig.co.uk and Ted
Lemon
isqlperl/ INFORMIX By William Hails, bill@tardis.co.uk
interperl/ INTERBASE By Buzz Moschetti, buzz@bear.com
oraperl/ ORACLE 6 & 7 By Kevin Stock (sadly no longer on the
net)
sybperl/ SYBASE 4 By Michael Peppler, mpeppler@itf.ch
ingperl/ INGRES By Tim Bunce timbo@ig.co.uk and Ted
Lemon
isqlperl/ INFORMIX By William Hails, bill@tardis.co.uk
interperl/ INTERBASE By Buzz Moschetti, buzz@bear.com
uniperl/ UNIFY 5.0 By Rick Wargo, rickers@coe.drexel.edu
pgperl/ POSTGRES By Igor Metz, metz@iam.unibe.ch
btreeperl/ NDBM perl extensions. By John Conover,
john@johncon.com
ctreeperl/ C-Tree perl extensions. By John Conover,
john@johncon.com
duaperl/ X.500 Directory User Agent. By Eric Douglas.
scripts/ Perl and shell scripts
rdb/ RDB is a perl RDBMS for ASCII files. By Walt Hobbs,
hobbs@rand.org
shql/ SHQL is an interactive SQL database engine. Written
as a
shell script, SHQL interprets SQL commands and
manipulates flat files based on those commands. By
Bruce Momjian, root@candle.uucp
xbase/ Perl scripts for accessing xBase style files (dBase
III)
refinfo/ Reference information
sqlsyntax/ Yacc and lex syntax and C source code for SQL1 and
SQL2
from
ftp.uu.net:/pub/uunet/published/oreilly/nutshell/yacclex,
and a draft SQL3 syntax from Jeff Fried
<jfried@informix.com>+
formats/ Details of file formats such as Lotus 1-2-3 .WK1
There are also a number of non SQL database interfaces for perl
available from ftp.demon.co.uk. These include:
Directory Target System Authors and notes
--------- ------------- -------------------------------------------
btreeperl NDBM extension John Conover (john@johncon.com)
ctreeperl CTree extension John Conover (john@johncon.com)
duaperl X.500 DUA Eric Douglas
rdb RDBMS Walt Hobbs (hobbs@rand.org)
shql SQL Engine Bruce Momjian (root@candle.uucp)
1.21) Which DBM should I use?
As shipped, Perl (version 5) comes with interfaces for several DBM
packages (SDBM, old DBM, NDBM, GDBM, Berkeley DBM) that are not
supplied
but either come with your system are readily accessible via FTP.
SDBM
is guaranteed to be there. For a comparison, see AnyDBM_File(3pm)
and DB_File(3pm).
1.22) Is there an SNMP aware Perl?
snmperl was written by Guy Streeter (streeter@ingr.com), and was
posted in late February 1993 to comp.protocols.snmp. It can be
found
archived at one of two (known) places:
Host liasun3.epfl.ch
Location: /pub/net/snmp
FILE -rw-rw-r-- 3407 Aug 11 1992 snmperl.README
FILE -rw-r--r-- 17678 Aug 11 1992 snmperl.tar.Z
Host ftp.cis.ufl.edu
Location: /pub/perl/scripts/snmp
Here is the gist of the README:
README $Revision: 2.3 $
This directory contains the source code to add callable C
subroutines
to perl. The subroutines implement the SNMP functions "get",
"getnext", and "set". They use the freely-distributable SNMP
package
(version 1.1b) from CMU.
USE:
There are four subroutines defined in the callable interface:
snmp_get, snmp_next, snmp_set, and snmp_error.
snmp_get and snmp_next implement the GET and GETNEXT operations,
respectively. The first two calling arguments are the hostname
and
Community string. The IP address of the host, as a dotted-quad
ASCII
string, may be used as the hostname. The rest of the calling
arguments are a list of variables. See the CMU package
documentation
for how variables may be specified.
snmp_set also takes hostname and Community string as arguments.
The
remaining arguments are a list of triples consisting of variable
name,
variable type, and value. The variable type is a string, such as
"INTEGER" or "IpAddress".
snmp_get, snmp_next, and snmp_set return a list containing
alternating variables and values. snmp_get and snmp_next will
simply
omit non-existent variables on return. snmp_set will fail
completely
if one of the specified variables does not exist (or is read-
only).
snmp_error will return a text string containing some error
information about the most recent snmp_get|next|set call, if it
had an
error.
OTHER NOTES:
I didn't find all the places where the CMU library writes to
stderr
or calls exit() directly.
The changes I made to mib.c involve the formatting of variable
values
for return to the caller. I took out the descriptive prefix so
the
string contains only the value.
Enumerated types are returned as a string containing the
symbolic
representation followed in parentheses by the numeric.
DISTRIBUTION and OWNERSHIP
perl and the CMU SNMP package have their own statements. Read
them.
The work I've done is free and clear. Just don't say you wrote it
if
you didn't, and don't say I wrote it if you change it.
Guy Streeter
streeter@ingr.com
April 1, 1992 (not a joke!)
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 2/5 - Information Sources
Message-ID: <perl-faq/part2_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
swrinde!hookup!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 2/5 - Information Sources
Supersedes: <perl-faq/part2_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:58 GMT
Organization: none
Lines: 579
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part2_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39242 comp.answers:8359
news.answers:32286
Archive-name: perl-faq/part2
Version: $Id: part2,v 2.3 1994/11/07 18:05:30 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to general information questions, mostly
of
about information sources.
2.1) Is there a USENET group for Perl?
Yes there is: comp.lang.perl. This group, which currently can get
up
to 100 messages per day, contains all kinds of discussions about
Perl;
everything from bug reports to new features to the history to
humour
and trivia. This is the best source of information about anything
Perl
related, especially what's new with Perl5. Because of it's vast
array
of topics, it functions as both a comp.lang.* style newsgroup
(providing technical information) and also as a rec.* style
newsgroup,
kind of a support group for Perl addicts (PerlAnon?).
Larry is a frequent poster to this group as well as most (all?) of
the
seasoned Perl programmers. Questions will be answered by some of
the
most knowledgable Perl Hackers, often within minutes of a question
being posted (give or take distribution times).
2.2) Have any books or magazine articles been published about Perl?
There have been quite a few books and articles. The most well
known
and most useful book for 4.036 and earlier is _Programming Perl_
(affectionately known as ``the Camel Book''), written by Larry and
Randal Schwartz*, published by O'Reilly & Associates as part of
their
Nutshell Handbook Series (ISBN: 0-937175-64-1). Besides serving
as a
reference guide for Perl, it also contains tutorial material and
is a
great source of examples and cookbook procedures, as well as wit
and
wisdom, tricks and traps, pranks and pitfalls. The code examples
contained therein are available via anonymous FTP from ftp.ora.com
in
/pub/examples/nutshell/programming_perl/perl.tar.Z or at
ftp.cis.ufl.edu in /pub/perl/ora/programming_perl. Corrections
and
additions to the book can be found in the Perl man page right
before
the BUGS section under the heading ERRATA AND ADDENDA.
A new version of the Camel book, revised and updated for Perl5 is
due
out sometime around spring of next year. Until then, the man
pages
distributed with the perl 5.000 source contain a wealth of
information
on the new features and old incompatibilities with perl4.036.
Also available is ``the Llama Book'', _Learning Perl_ by Randal
Schwartz, another Nutshell book. This book is a collection of
some of
the best introductory and tutorial information available about
Perl. A
definite must for novice Perl users. The examples and code from
this
book are available from the same places as the Camel book code.
(ISBN:
1-56592-042-2)
If you can't find these books in your local technical bookstore,
they
may be ordered directly from O'Reilly by calling 1-800-998-9938 if
in
North America and 1-707-829-0515 otherwise.
Larry routinely carries around a camel stamp to use when
autographing
copies of his book. If you can catch him at a conference you can
usually get him to sign your book for you.
Larry Wall has published a 3-part article on perl in Unix World
(August through October of 1991), and Rob Kolstad also had a 3-
parter
in Unix Review (May through July of 1990). Tom Christiansen also
has
a brief overview article in the trade newsletter Unix Technology
Advisor from November of 1989. You might also investigate "The
Wisdom
of Perl" by Gordon Galligher from SunExpert magazine; April 1991
Volume 2 Number 4. The Dec 92 Computer Language magazine also
contains a cover article on Perl, "Perl: the Programmers Toolbox".
Many other articles on Perl have been recently published. If you
have references, especially on-line copies, please mail them to
the FAQ maintainer for inclusion is this notice.
The USENIX LISA (Large Installations Systems Administration)
Conference
have for several years now included many papers of tools written
in
Perl. Old proceedings of these conferences are available; look in
your current issue of ";login:" or send mail to office@usenix.org
for further information.
At this point, the "writing committe" (Larry, Randal, and Tom; aka
<perlbook@perl.com>) is looking at:
o A heavy rewrite of the Camel to update it to Perl5. Expect the
tutorial section to be cut in deference to the Llama.
o A light update of the Llama to eliminate the "I think perl5 will
do ..." and a change to "Perl5 will do ..."
o A new book, "Learning More Perl" (working title), a sequel to the
Llama, covering what wasn't covered in the Llama including Perl5.
According to Randal, this is the current priority. However, he
notes
that the new Camel won't be out until sometime in the spring of
next
year, at the earliest.
Prentice Hall also has two perl books, either on the shelves or in
the
works. The first is ``Perl by Example'' by Ellie Quigley. (385
pages,
$26.96, ISBN 0-13-122839-0) A perl tutorial (perl4); every feature
is
presented via an annotated example and sample output.
The second book is called ``Software Engineering with Perl'' by
Carl
Dichter and Mark Pease. Randal Schwartz has reviewed the second
book
(SEwP) and has this to say about it:
SWwP is not meant as instruction in the Perl language, but rather
as an example of how Perl may be used to assist in the semi-formal
software engineering development cycles. There's a lot of Perl
code that's fairly well commented, but most of the book describes
software engineering methodologies. For the perl-challenged,
there's a *light* treatment of the language as well, but they refer
to the llama and the camel for the real meat.
Japan seems to be jumping with Perl books. If you can read
japanese
here are a few you might be interested in. Thanks to Jeffrey
Friedl*
for this list (NOTE: my screen cannot handle japanese characters,
so
this is all in English for the moment NOTE2: These books are
written
in Japanese, these titles are just translations):
Title: Welcome to Perl Country
Authors: Kaoru Maeda, Hiroshi Koyama, Yasushi Saito and Arihito
Fuse
Publisher: Science Company Date: April 25, 1993
ISBN: 4-7819-0697-4 Price: 2472Y
Comments: Written during the time the Camel book was being
translated. A useful introduction, but uses jperl (Japanese Perl)
which is not necessarily compatible.
Title: Perl Writing Methods (Perl Calligraphy?)
Author: Toshiyuki Masui
Publisher: ASCII Corporation Date: July 1, 1993
ISBN: 4-7561-0281-6 Price: 3200Y
Comments: More advanced than "Welcome.." and not meant as an
introduction. Uses the standard perl and has examples for handling
Japanese text.
Title: Introduction to Perl
Author: Shinji Kono
Publisher: ASCII Corporation Date: July 11, 1994
ISBN: 4-7561-0292-1 Price: 1800Y
Comments: Uses the interactive Perl debugger to explain how things
work.
Title: Programming Perl
Authors: L Wall & R Schwartz Translator: Yoshiyuri Kondo
Publisher: Softbank Corporation Date: February 28, 1993
ISBN: 4-89052-384-7 Price: 4500Y
Comments: Official Japanese translation. Somewhat laced with
translator notes to explain the humour. The most useful book.
There is also a German translation of Programming Perl. It is
available
from Hanser Verlag:
Title: Programmieren in Perl
ISBN: 3-446-17257-2
2.3) When will the Camel and Llama books be updated?
When they do. :-) Actually, we're looking at having them in print
about 6 months from now (for floating values of now :-). Send the
writing committee mail (perlbook@perl.com) mail if you have
suggestions.
2.4) What FTP resources are available?
Within the past year, several ftp sites have sprung up for Perl
and
Perl related items. The site with the biggest repository of Perl
scripts right now seems to be ftp.cis.ufl.edu [128.227.100.198].
The
scripts directory has an INDEX with over 400 lines in it, each
describing what the script does. The src directory has sources
and/or
binaries for a number of different perl ports, including MS-Dos,
Macintosh and Windows/NT. This is maintained by me, Steve*.
Note: I've changed jobs recently and am not currently directly
on the Internet. This means this site may get a little out of
date until I can get back up to UF and update it. However, I
did set up automatic mirrors to many sites, so much of it should
remain uptodate. (If only Larry would put the beta patches on
netlabs....)
Note: European users please use the site src.doc.ic.ac.uk
[149.169.2.1] in /pub/computing/programming/languages/perl/
The link speed would be a lot better for all. Contact
L.McLoughlin@doc.ic.ac.uk for more information. It is updated
daily.
This may not be working yet. I'm working with Lee to get it
setup.
There are also a number of other sites. I'll add more of them as
I get
information on them.
2.5) What WWW/gopher resources are available?
The World Wide Web is exploding with new Perl sites all the time.
Some
of the more notable ones are:
http://www.cis.ufl.edu/perl
http://www.metronet.com/1h/perlinfo, which has a great section on
Perl5.
http://www.eecs.nwu.edu/perl/perl.html
http://web.nexor.co.uk/perl/perl.html, a great site for
European
and UK users.
2.6) Can people who don't have access to USENET get comp.lang.perl?
"Perl-Users" is the mailing list version of the comp.lang.perl
newsgroup. If you're not lucky enough to be on USENET you can
post to
comp.lang.perl by sending to one of the following addresses.
Which one
will work best for you depends on which nets your site is hooked
into.
Ask your local network guru if you're not certain.
Internet: PERL-USERS@VIRGINIA.EDU
Perl-Users@UVAARPA.VIRGINIA.EDU
BitNet: Perl@Virginia
uucp: ...!uunet!virginia!perl-users
The Perl-Users list is bidirectionally gatewayed with the USENET
newsgroup comp.lang.perl. This means that VIRGINIA functions as a
reflector. All traffic coming in from the non-USENET side is
immediately posted to the newsgroup. Postings from the USENET
side are
periodically digested and mailed out to the Perl-Users mailing
list. A
digest is created and distributed at least once per day, more
often if
traffic warrants.
All requests to be added to or deleted from this list, problems,
questions, etc., should be sent to:
Internet: Perl-Users-Request@Virginia.EDU
Perl-Users-Request@uvaarpa.Virginia.EDU
BitNet: Perl-Req@Virginia
uucp: ...!uunet!virginia!perl-users-request
Coordinator: Marc Rouleau <mer6g@VIRGINIA.EDU>
2.7) Are archives of comp.lang.perl available?
Yes, there are. ftp.cis.ufl.edu:/pub/perl/comp.lang.perl/monthly
has
an almost complete collection dating back to 12/89 (missing 08/91
through 12/93). They are kept as one large file for each month.
A more sophisticated query and retrieval mechanism is desirable.
Preferably one that allows you to retrieve article using a fast-
access
indices, keyed on at least author, date, subject, thread (as in
"trn")
and probably keywords. Right now, the MH pick command works for
this,
but it is very slow to select on 18000 articles.
If you have, or know where I can find, the missing sections,
please let
perlfaq@perl.com know.
2.8) Is there a WAIS server for comp.lang.perl?
Yes there is. Set your WAIS client to
archive.orst.edu:9000/comp.lang.perl. According to their
introduction,
they have a complete selection from 1989 on.
Bill Middleton <wjm@feenix.metronet.com> offers this:
"I have setup a perl script retrieval service and WaisSearch here
at
feenix. To check it out, just point your gopher at us, and select
the
appropriate menu option. The WaisSearch is of the iubio type,
which
means you can do boolean searching. Thus you might try something
like:
caller
ioctl and fcntl
grep and socket not curses
and other things to see examples of how other folks have done this
or that. This service is still under construction, but I'd like
to
get feedback, if you have some time.
There's also a WaisSearch into all the RFC's and some other fairly
nifty stuff."
2.9) What other sources of information about Perl or training are
available?
Johan Vromans* created an beautiful reference guide. The
reference
guide comes with the Camel book in a nice, glossy format. The
LaTeX
(source) and PostScript (ready to print) versions are available
for FTP
from ftp.cs.ruu.nl:/pub/DOC/perlref-4.036.1.tar.Z in Europe or
from
ftp.cis.ufl.edu:/pub/perl/doc/perlref-4.036.tar.gz in the United
States. Obsolete versions in TeX or troff may still be available,
but
these versions don't print as nicely. See also:
[] ftp://ftp.uu.net/languages/perl/perlref-4.036.1.tar.gz
[] ftp://ftp.cs.ruu.nl/pub/DOC/perlref-4.036.1.tar.gz
[] ftp://ftp.khoros.unm.edu/pub/perl/perlref-4.036.1.tar.gz
Johan is working on an update to this document to include perl5
functionality, which he hopes to release by Christmas 1994.
There is a #Perl channel on IRC (Internet Relay Chat) where Tom
and
Randal have been known to hang out. Here you can get immediate
answers
to questions from some of the most well-known Perl Hackers.
The perl5-porters (perl5-porters@isu.edu) mailing list was created
to
aid in communication among the people working on perl5. However,
it
has overgrown this function and now also handles a good deal of
traffic
about perl internals.
2.10) Where can I get training classes on Perl?
USENIX, LISA, SUG, WCSAS, AUUG, FedUnix and Europen sponsor
tutorials
of varying lengths on Perl at the System Administration and
General
Conferences. These public classes are typically taught by Tom
Christiansen*.
In part, Tom and Randal teach Perl to help keep bread on their
tables
long enough while they continue their pro bono efforts of
documenting
perl (Tom keeps writing more man pages for it :-) and expanding
the
perl toolkit through extension libraries, work which they enjoy
doing
as it's fun and helps out the whole world, but which really
doesn't
pay the bills. Such is the nature of free(ly available) software.
Send mail to <perlclasses@perl.com> for details and availability.
Tom is also available to teach on-site classes, included courses
on
advanced perl and perl5. Classes run anywhere from one day to
week
long sessions and cover a wide range of subject matter. Classes
can
include lab time with exercises, a generally beneficial aspect.
If you
would like more information regarding Perl classes or when the
next
public appearances are, please contact Tom directly.
Randal Schwartz* provides a 2-day lecture-only and a 4-5 day
lecture-lab
course based on his popular book "Learning Perl". For details,
contact
Randal directly via email or at 1.503.777.0095.
Internet One provides a 2 day "Introduction to Perl" and 2 day
"Advanced Perl" workshop. The 50% hands-on and 50% lecture format
allow attendees to write several programs themselves. Supplied
are the user manuals, reference copies of Larry Wall's "Program-
ming Perl", and a UNIX directory of all training examples and
labs. To obtain outlines, pricing, or scheduling information, use
the following:
o Phone: 1.303.444.1993
o Email: info@InternetOne.COM
o See our Ad in the "SysAdmin" magazine
o View the outlines via the Web: http://www.InternetOne.COM/
2.11) What companies use or ship Perl?
At this time, the known list of companies that ship Perl includes
at
least the following, although some have snuck it into /usr/contrib
or
its moral equivalent:
BSDI
Comdisco Systems
CONVEX Computer Corporation
Crosspoint Solutions
Dell
DRD Corporation
IBM (SP systems)
Intergraph
Kubota Pacific
Netlabs
SGI (without taintperl)
Univel
Furthermore, the following vendors are reported to begin shipping
perl
standard with their systems in the very near future:
Sun
Some companies ship it on their "User Contributed Software Tape",
such as DEC and HP. Apple Computer has shipped the MPW version of
Macintosh Perl on one of their Developer CDs
(Essentials*Tools*Objects
#11) (and they included it under "Essentials" :-)
Many other companies use Perl internally for purposes of tools
development, systems administration, installation scripts, and
test
suites. Rumor has it that the large workstation vendors (the TLA
set)
are seriously looking into shipping Perl with their standard
systems
"soon".
úÿ
People with support contracts with their vendors are actively
encouraged to submit enhancement requests that Perl be shipped
as part of their standard system. It would, at the very least,
reduce the FTP load on the Internet. :-)
If you know of any others, please send them in.
2.12) Is there commercial, third-party support for Perl?
Not really. Although perl is included in the GNU distribution, at
last
check, Cygnus does not offer support for it. However, it's
unclear
whether they've ever been offered sufficient financial incentive
to do
so.
On the other hand, you do have comp.lang.perl as a totally gratis
support mechanism. As long as you ask "interesting" questions,
you'll
probably get plenty of help. :-)
While some vendors do ship Perl with their platforms, that doesn't
mean
they support it on arbitrary other platforms. And in fact, all
they'll
probably do is forward any bug reports on to Larry. In practice,
this
is far better support than you could hope for from nearly any
vendor.
The companies who won't use something unless they can pay money
for it
will be left out. Often they're motivated by wanting someone whom
they
could sue. If all they want is someone to help them out with Perl
problems, there's always the net. And if they really want to pay
someone for that help, well, Tom and Randal are always looking for
a
job. :-)
If companies want "commercial support" for it badly enough, speak
up --
something might be able to be arranged.
2.13) What is a JAPH? What does "Will hack perl for ..." mean?
These are the "just another perl hacker" signatures that some
people
sign their postings with. About 100 of the of the earlier ones
are
available from the various FTP sites.
When people started running out of tricky and interesting JAPHs,
some
of them turned to writing "Will hack perl for ..." quotes. While
sometimes humourous, they just didn't have the flair of the JAPHs
and
have since almost completely vanished.
2.14) Where can I get a list of Larry Wall witticisms?
Over a hundred quips by Larry, from postings of his or source
code,
can be found in many of the FTP sites or through the World Wide
Web at
"ftp://ftp.cis.ufl.edu/pub/perl/misc/lwall-quotes"
2.15) What are the known bugs?
These apply to version 5 of perl. See also: `What does "Malformed
command links" mean?' for a version 4 bug.
The README says it's a pre-release.
Workaround: ignore this sentence.
Installs perl0.000 and sperl0.000 instead of 5.000.
Workaround: rename the files.
The debugger appears to be broken on "my" variables;
Workaround: none yet
Recursive signal handlers eventually core dump.
Workaround: ease up on the ^C key.
The following code misbehaves: print ++$_ . "\n" until /0/;
Workaround: initialize your variable
Destructors can clobber $@ on exit from an eval
Workaround: local $@; eval {...};
2.16) Where should I post bugs?
The best place to send your bug is <perlbug@perl.com>, which is
currently just alias for <perl5-porters@isu.edu>. You may
subscribe
to the list in the customary fashion via mail to
<perl5-porters-request@isu.edu>. Feel free to post your bugs to
the
comp.lang.perl newsgroup as well, but do make sure they still go
to
the mailing list.
To enhance your chances of getting any bug you report fixed:
1. Try to narrow the problem down to as small a piece of code as
possible. If you can get it down to 1 line of Perl then so
much
the better.
2. Include a copy of the output from the myconfig script from the
Perl source distribution in your posting.
2.17) Where should I post source code?
You should post source code to whichever group is most
appropriate,
but feel free to cross-post to comp.lang.perl. If you want to
cross-post to alt.sources, please make sure it follows their
posting standards, including setting the Followups-To header
line to NOT include alt.sources; see their FAQ for details.
2.18) Where can I learn about object-oriented Perl programming?
The perlobj(1) man page is a good place to start, and then you can
check out the excellent perlbot(1) man page written by the dean of
perl
o-o himself, Dean Roehrich. Areas covered include the following:
Idx Subsections in perlobj.1 Lines
1 NAME 2
2 DESCRIPTION 16
3 An Object is Simply a Reference 60
4 A Class is Simply a Package 31
5 A Method is Simply a Subroutine 34
6 Method Invocation 75
7 Destructors 14
8 Summary 7
Idx Subsections in perlbot.1 Lines
1 NAME 2
2 INTRODUCTION 9
3 Instance Variables 43
4 Scalar Instance Variables 21
5 Instance Variable Inheritance 35
6 Object Relationships 33
7 Overriding Superclass Methods 49
8 Using Relationship with Sdbm 45
9 Thinking of Code Reuse 111
The section on instance variables should prove very helpful to
those
wondering how to get data inheritance in perl.
2.19) Where can I learn about linking C with Perl? [h2xs]
While it used to be deep magic, how to do this is now revealed in
the
perlapi(1), perlguts(1), and perlcall(1) man pages, which treat
with
this matter extensively.
2.20) What is perl.com?
Perl.com is just Tom's domain name, registered as dedicated to
"Perl
training and consulting". While not a proper ftp site (he hasn't
got
the bandwidth (yet)), it does serve as a clearinghouse for certain
perl related mailing list. That means that you should always be
able
to get to Larry, Tom, or Randal through that host. The following
aliases work:
perl-packrats: The archivist list
perl-porters: The porters list
perlbook: The Camel/Llama/Alpaca writing committee
perlbugs: The bug list (perl-porters for now)
perlclasses: Info on Perl training
perlfaq: Submissions/Errata to the Perl FAQ
(Tom and Steve)
perlrefguide: Submissions/Errata to the Perl FAQ
(Johan)
y
2.21) What do the asterisks (*) throughout the FAQ stand for?
To keep from cluttering up the FAQ and for easy reference all
email
addresses have been collected in this location. For each person
listed, I offer my thanks for their input and help.
* Larry Wall <lwall@netlabs.com>
* Tom Christiansen <tchrist@wraeththu.cs.colorado.edu>
* Stephen P Potter <spp@vx.com>
* Andreas Koenig <k@franz.ww.TU-Berlin.DE>
* Bill Eldridge <bill@cognet.ucla.edu>
* Buzz Moschetti <buzz@toxicavenger.bear.com>
* Casper H.S. Dik <casper@fwi.uva.nl>
* David Muir Sharnoff <muir@tfs.com>
* Dean Roehrich <roehrich@ironwood.cray.com>
* Dominic Giampaolo <dbg@sgi.com>,
* Frederic Chauveau <fmc@pasteur.fr>
* Gene Spafford <spaf@cs.purdue.edu>
* Guido van Rossum <guido@cwi.nl>
* Henk P Penning <henkp@cs.ruu.nl>
* Jeff Friedl <jfriedl@omron.co.jp>
* Johan Vromans <jv@NL.net>
* John Dallman <jgd@cix.compulink.co.uk>
* John Lees <lees@pixel.cps.msu.edu>
* John Ousterhout <ouster@eng.sun.com>
* Jon Biggar <jon@netlabs.com>
* Malcolm Beattie <mbeattie@sable.ox.ac.uk>
* Michael D'Errico <mike@software.com>
* Randal Schwartz <merlyn@stonehenge.com>
* Roberto Salama <rs@fi.gs.com>
* Steven L Kunz <skunz@iastate.edu>
* Theodore C. Law <TEDLAW@TOROLAB6.VNET.IBM.COM>
* Thomas R. Kimpton <tom@dtint.dtint.com>
* Timothy Murphy <tim@maths.tcd.ie>
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 3/5 - Programming Aids
Message-ID: <perl-faq/part3_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 3/5 - Programming Aids
Supersedes: <perl-faq/part3_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:38 GMT
Organization: none
Lines: 424
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part3_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39238 comp.answers:8355
news.answers:32282
Archive-name: perl-faq/part3
Version: $Id: part3,v 2.1 1994/10/25 13:56:19 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to general information questions, mostly
about programming aids.
3.1) How can I use Perl interactively?
The easiest way to do this is to run Perl under its debugger. If
you
have no program to debug, you can invoke the debugger on an
`empty'
program like this:
perl -de 0
(The more positive hackers prefer "perl -de 1". :-)
Now you can type in any legal Perl code, and it will be
immediately
evaluated. You can also examine the symbol table, get stack
backtraces, check variable values, and if you want to, set
breakpoints
and do the other things you can do in a symbolic debugger.
3.2) Is there a Perl profiler?
While there isn't one included with the perl source distribution
(yet)
various folks have written packages that allow you to do at least
some
sort of profiling. The strategy usually includes modifying the
perl
debugger to handle profiling. Authors of these packages include
Wayne Thompson <me@anywhere.EBay.Sun.COM>
Ray Lischner <lisch@sysserver1.mentor.com>
Kresten Krab Thorup <krab@iesd.auc.dk>
The original articles by these folks containing their profilers
are
available on convex.com in /pub/perl/information/profiling.shar
via
anon ftp.
3.3) Is there a yacc for Perl?
Yes!! It's a version of Berkeley yacc that outputs Perl code
instead
of C code! You can get this from ftp.sterling.com [192.124.9.1]
in
/local/perl-byacc1.8.1.tar.Z, or send the author mail for details.
3.4) Is there a pretty-printer for Perl?
That depends on what you mean. If you want something that works
like
vgrind on Perl programs, then the answer is "yes, nearly". Here's
a
vgrind entry for perl:
PERL|perl|Perl:\
:pb=^\d?(sub|package)\d\p\d:\
:bb={:be=}:cb=#:ce=$:sb=":se=\e":lb=':\
:le=\e':tl:\
:id=_:\
:kw=\
if for foreach unless until while continue else elsif \
do eval require \
die exit \
defined delete reset \
goto last redo next dump \
local undef return \
write format \
sub package
It doesn't actually do everything right; in particular,
things like $#, $', s#/foo##, and $foo'bar all confuse it.
David Levine uses this:
# perl 4.x David Levine <levine@ics.uci.edu> 05
apr
1993
# Derived from Tom Christiansen's perl vgrindef. I'd like to
treat all
of
# perl's built-ins as keywords, but vgrind fields are limited
to
1024
# characters and the built-ins overflow that (surprise :-). So,
I
didn't
# include the dbm*, end*, get*, msg*, sem*, set*, and shm*
functions.
I
# couldn't come up with an easy way to distinguish beginnings of
literals
# ('...') from package prefixes, so literals are not marked.
# Be sure to:
# 1) include whitespace between a subprogram name and its opening
{
# 2) include whitespace before a comment (so that $# doesn't get
# interpreted as one).
perl4:\
:pb=^\d?(sub|package)\d\p\d:\
:id=$%@_:\
:bb=\e{:be=\e}:cb=\d\e#:ce=$:sb=\e":se=\e":\
:kw=accept alarm atan2 bind binmode caller chdir chmod chop \
chown chroot close closedir connect continue cos crypt defined
delete \
die do dump each else elsif eof eval exec exit exp fcntl fileno
flock \
for foreach fork format getc gmtime goto grep hex if include index
int \
ioctl join keys kill last length link listen local localtime log
lstat \
m mkdir next oct open opendir ord pack package pipe pop print
printf \
push q qq qx rand read readdir readlink recv redo rename require
reset \
return reverse rewinddir rindex rmdir s scalar seek seekdir select
send \
shift shutdown sin sleep socket socketpair sort splice split
sprintf \
sqrt srand stat study sub substr symlink syscall sysread system \
syswrite tell telldir time times tr truncate umask undef unless
unlink \
unpack unshift until utime values vec wait waitpid wantarray warn
while \
write y:
If what you mean is whether there is a program that will reformat
the
program much as indent(1) will do for C, then the answer is no.
The
complex feedback between the scanner and the parser (as in the
things
that confuse vgrind) make it challenging at best to write a stand-
alone
Perl parser.
3.5) There's an a2p and an s2p; why isn't there a p2c (perl-to-C)?
Because the Pascal people would be upset that we stole their name.
:-)
The dynamic nature of Perl's do and eval operators (and remember
that
constructs like s/$mac_donald/$mac_gregor/eieio count as an eval)
would
make this very difficult. To fully support them, you would have
to put
the whole Perl interpreter into each compiled version for those
scripts
using them. This is what undump does right now, if your machine
has it.
If what you're doing will be faster in C than in Perl, maybe it
should
have been written in C in the first place. For things that ought
to be
written in Perl, the interpreter will be just about as fast,
because the
pattern matching routines won't work any faster linked into a C
program.
Even in the case of simple Perl programs that don't do any fancy
evals,
the
major gain would be in compiling the control flow tests, with the
rest
still being a maze of twisty, turny subroutine calls. Since these
are not
usually the major bottleneck in the program, there's not as much
to be
gained via compilation as one might think.
However, we're still looking for someone to generate byte-compiled
code for Perl, or eventually even C code out of it. These are
probably masters and PhD thesis topics respectively, and no one
has begun work on it yet.
3.6) Where can I get a perl-mode for emacs?
Since Emacs version 19 patchlevel 22 or so, there has been both a
perl-mode.el and support for the perl debugger built in. These
should
come with the standard Emacs 19 distribution.
In the perl source directory, you'll find a directory called
"emacs", which contains several files that should help you.
3.7) Is there a Perl shell?
Not really. Perl is a programming language, not a command
interpreter. There is a very simple one called "perlsh"
included in the Perl source distribution. It just does this:
$/ = ''; # set paragraph mode
$SHlinesep = "\n";
while ($SHcmd = <>) {
$/ = $SHlinesep;
eval $SHcmd; print $@ || "\n";
$SHlinesep = $/; $/ = '';
}
Not very interesting, eh?
Daniel Smith <dansmith@autodesk.com> is working on an interactive
Perl
shell called SoftList. It's currently at version 3.0beta.
SoftList
3.0 has tcsh-like command line editing, can let you define a file
of
aliases so that you can run chunks of perl or UNIX commands, and
so
on. You can send mail to him for further information and
availability.
3.8) How can I use curses with perl?
In release 4 of perl, the only way to do this was was to build a
curseperl binary by linking in your C curses library as described
in
the usub subdirectory of the perl sources. This requires a
modicum of
work, but it will be reasonably fast since it's all in C (assuming
you
consider curses reasonably fast. :-) Programs written using this
method require the modified curseperl, not vanilla perl, to run.
While this is something of a disadvantage, experience indicates
that
it's better to use curseperl than to try to roll your own using
termcap directly.
Fortunately, in version 5, Curses is a dynamically loaded
extension
by William Setzer*. You should be able to pick it up wherever you
get Perl 5 from, or at least these places:
ftp://ftp.ncsu.edu/pub/math/wsetzer/cursperl5a6.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/cursperl5a6.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/cursperl5a6.tar.gz
For a good example of using (v4) curseperl, you might want to pick
up a
copy of Steven L Kunz's* "perl menus" package ("menu.pl") via
anonymous FTP from "ftp.iastate.edu". It's in the /pub/perl as
menu.pl.v2.3.shr1
menu.pl.v2.3.shr2
menu.pl.v2.3.tar.Z
menus.pl is a complete menu front-end for curseperl and
demonstates
a lot of things (plus it is useful to boot if you want full-screen
menu selection ability).
Another possibility is to use Henk Penning's cterm package, a
curses
emulation library written in perl. cterm is actually a separate
program with which you communicate via a pipe. It is available
from
ftp.cs.ruu.nl [131.211.80.17] via anonymous ftp. in the directory
pub/PERL. You may also acquire the package via email in
compressed,
uuencoded form by sending a message to mail-server@cs.ruu.nl
containing these lines:
begin
send PERL/cterm.shar.Z
end
See the question on retrieving perl via mail for more information
on
how to retrieve other items of interest from the mail server
there.
3.9) How can I use X with Perl?
Right now, you have several choices. If you are still using
perl4, use
the WAFE or STDWIN packages, or try to make your own usub binding.
However, if you've upgraded to version 5, you have several
exciting
possibilities, with more popping up each day. Right now, Tk and
Sx
are the best known such extensions.
If you like the tk package, you should get the Tk extension kit,
written by Malcolm Beattie*. Here are some places to get it:
Tk (as in tcl/tk, but sans tcl)
ftp://ftp.cis.ufl.edu/pub/perl/src/tkperl/tkperl5a4.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/tkperl5a4.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/tkperl/tkperl5a4.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/tkperl5a4.tar.gz
ftp://black.ox.ac.uk/src/ALPHA/tkperl5a4.tar.gz
(try 5a5 everywhere after 2pm UST Thu 20 Oct 1994, as in)
ftp://sable.ox.ac.uk/pub/perl/tkperl5a5.tar.gz
You may also use the old Sx package, (Athena & Xlib), written by
originally written by by Dominic Giampaolo*, then and rewritten
for Sx
by Frederic Chauveau*.fr>. It's available from these sites:
ftp://ftp.pasteur.fr/pub/Perl/Sx.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/Sx.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/Sx.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/PerlDoc.ps.gz
STDWIN is a library written by Guido van Rossum* (author of the
Python
programming language) that is portable between Mac, Dos and X11.
One
could write a Perl agent to speak to this STDWIN server.
WAFE is a package that implements a symbolic interface to the
Athena
widgets (X11R5). A typical Wafe application consists in our
framework
of two parts: the front-end (we call it Wafe for
Widget[Athena]front
end) and an application program running typically as a separate
process. The application program can be implemented in an
arbitrary
programming language and talks to the front-end via stdio. Since
Wafe
(the front-end) was developed using the extensible TCL shell (cite
John
Ousterhout), an application program can dynamically submit
requests to
the front-end to build up the graphical user interface; the
application can even down-load application specific procedures
into
the front-end. The distribution contains sample application
programs
in Perl, GAWK, Prolog, TCL, and C talking to the same Wafe binary.
Many of the demo applications are implemented in Perl. Wafe 0.9
can
be obtained via anonymous ftp from
ftp.wu-wien.ac.at[137.208.3.5]:pub/src/X11/wafe-0.9.tar.Z
Alternatively, you could use wish from tcl.
#!/usr/local/bin/perl
#####################################################################
# An example of calling wish as a subshell under Perl and
# interactively communicating with it through sockets.
#
# The script is directly based on Gustaf Neumann's perlwafe
script.
#
# Dov Grobgeld dov@menora.weizmann.ac.il
# 1993-05-17
#####################################################################
$wishbin = "/usr/local/bin/wish";
die "socketpair unsuccessful: $!!\n" unless
socketpair(W0,WISH,1,1,0);
if ($pid=fork) {
select(WISH); $| = 1;
select(STDOUT);
# Create some TCL procedures
print WISH 'proc echo {s} {puts stdout $s; flush stdout}',"\n";
# Create the widgets
print WISH <<TCL;
# This is a comment "inside" wish
frame .f -relief raised -border 1 -bg green
pack append . .f {top fill expand}
button .f.button-pressme -text "Press me" -command {
echo "That's nice."
}
button .f.button-quit -text quit -command {
echo "quit"
}
pack append .f .f.button-pressme {top fill expand} \\
.f.button-quit {top expand}
TCL
;
# Here is the main loop which receives and sends commands
# to wish.
while (<WISH>) {
chop;
print "Wish sais: <$_>\n";
if (/^quit/) { print WISH "destroy .\n"; last; }
}
wait;
} elsif (defined $pid) {
open(STDOUT, ">&W0");
open(STDIN, ">&W0");
close(W0);
select(STDOUT); $| = 1;
exec "$wishbin --";
} else {
die "fork error: $!\n";
}
3.10) Can I dynamically load C user routines?
Yes -- dynamic loading comes with the distribution. That means
that
you no longer need 18 different versions of fooperl floating
around.
In fact, all of perl can be stuck into a libperl.so library and
then your /usr/local/bin/perl binary reduced to just 50k or so.
See DynLoader(3pm) for details.
In perl4, the answer is kinda. One package has been released that
does
this, by Roberto Salama*. He writes:
Here is a version of dylperl, dynamic linker for perl. The code
here is
based on Oliver Sharp's May 1993 article in Dr. Dobbs Journal
(Dynamic
Linking under Berkeley UNIX).
dyl.h
dyl.c - code extracted from Oliver Sharp's article
hash.h
hash.c - Berkeley's hash functions, should use perl's but
could not be bothered
dylperl.c - perl usersubs
user.c - userinit function
sample.c - sample code to be dyl'ed
sample2.c - "
test.pl - sample perl script that dyl's sample*.o
The Makefile assumes that uperl.o is in /usr/local/src/perl/...
You
will probable have to change this to reflect your installation.
Other
than that, just type 'make'...
The idea behind being able to dynamically link code into perl is
that
the linked code should become perl functions, i.e. they can be
invoked
as &foo(...). For this to happen, the incrementally loaded code
must
use the perl stack, look at sample.c to get a better idea.
The few functions that make up this package are outlined below.
&dyl("file.o"): dynamically link file.o. All functions and non-
static
variables become visible from within perl. This
function returns a pointer to an internal hash table
úÿ
corresponding to the symbol table of the newly loaded
code.
eg: $ht = &dyl("sample.o")
This function can also be called with the -L and -l ld options.
eg: $ht = &dyl(""sample2.o", "-L/usr/lib", "-lm")
will also pick up the math library if sample.o
accesses any symbols there.
&dyl_find("func"): find symbol 'func' and return its symbol table
entry
&dyl_functions($ht): print the contents of the internal hash table
&dyl_print_symbols($f): prints the contents of the symbol returned
by
dyl_find()
There is very little documentation, maybe something to do for a
future
release. The files sample.o, and sample2.o contain code to be
incrementally loaded, test.pl is the test perl script.
Comments are welcome. I submit this code for public consumption
and,
basically, am not responsible for it in any way.
3.11) What is undump and where can I get it?
The undump program comes from the TeX distribution. If you have
TeX,
then you may have a working undump. If you don't, and you can't
get
one, *AND* you have a GNU emacs working on your machine that can
clone
itself, then you might try taking its unexec() function and
compiling
Perl with -DUNEXEC, which will make Perl call unexec() instead of
abort(). You'll have to add unexec.o to the objects line in the
Makefile. If you succeed, post to comp.lang.perl about your
experience
so others can benefit from it.
If you have a version of undump that works with Perl, please
submit
its anon-FTP whereabouts to the FAQ maintainer.
3.12) How can I get '#!perl' to work under MS-DOS?
John Dallman* has written a program "#!perl.exe" which will do
this.
It is available through anonymous ftp from ftp.ee.umanitoba.ca in
the
directory /pub/msdos/perl/hbp_20.zip. This program works by
finding
the script and perl.exe, building a command line and running
perl.exe
as a child process. For more information on this, contact John
directly.
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 4/5 - General Programming
Message-ID: <perl-faq/part4_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 4/5 - General Programming
Supersedes: <perl-faq/part4_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:53 GMT
Organization: none
Lines: 1065
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part4_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39241 comp.answers:8358
news.answers:32285
Archive-name: perl-faq/part4
Version: $Id: part4,v 2.3 1994/11/07 18:06:47 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to the following questions about General
Programming, Regular Expressions (Regexp) and Input/Output:
4.1) What are all these $@%*<> signs and how do I know when to use
them?
Those are type specifiers:
$ for scalar values
@ for indexed arrays
% for hashed arrays (associative arrays)
* for all types of that symbol name. These are sometimes used like
pointers
<> are used for inputting a record from a filehandle.
See the question on arrays of arrays for more about Perl pointers.
While there are a few places where you don't actually need these
type
specifiers, except for files, you should always use them. Note
that
<FILE> is NOT the type specifier for files; it's the equivalent of
awk's
getline function, that is, it reads a line from the handle FILE.
When
doing open, close, and other operations besides the getline
function on
files, do NOT use the brackets.
Beware of saying:
$foo = BAR;
Which wil be interpreted as
$foo = 'BAR';
and not as
$foo = <BAR>;
If you always quote your strings, you'll avoid this trap.
Normally, files are manipulated something like this (with
appropriate
error checking added if it were production code):
open (FILE, ">/tmp/foo.$$");
print FILE "string\n";
close FILE;
If instead of a filehandle, you use a normal scalar variable with
file
manipulation functions, this is considered an indirect reference
to a
filehandle. For example,
$foo = "TEST01";
open($foo, "file");
After the open, these two while loops are equivalent:
while (<$foo>) {}
while (<TEST01>) {}
as are these two statements:
close $foo;
close TEST01;
but NOT to this:
while (<$TEST01>) {} # error
^
^ note spurious dollar sign
This is another common novice mistake; often it's assumed that
open($foo, "output.$$");
will fill in the value of $foo, which was previously undefined.
This
just isn't so -- you must set $foo to be the name of a filehandle
before you attempt to open it.
4.2) How come Perl operators have different precedence than C
operators?
Actually, they don't; all C operators have the same precedence in
Perl as
they do in C. The problem is with a class of functions called
list
operators, e.g. print, chdir, exec, system, and so on. These are
somewhat
bizarre in that they have different precedence depending on
whether you
look on the left or right of them. Basically, they gobble up all
things
on their right. For example,
unlink $foo, "bar", @names, "others";
will unlink all those file names. A common mistake is to write:
unlink "a_file" || die "snafu";
The problem is that this gets interpreted as
unlink("a_file" || die "snafu");
To avoid this problem, you can always make them look like function
calls
or use an extra level of parentheses:
unlink("a_file") || die "snafu";
(unlink "a_file") || die "snafu";
In perl5, there are low precedence "and", "or", and "not"
operators,
which bind les tightly than comma. This alllows you to write:
unlink $foo, "bar", @names, "others" or die "snafu";
Sometimes you actually do care about the return value:
unless ($io_ok = print("some", "list")) { }
Yes, print() returns I/O success. That means
$io_ok = print(2+4) * 5;
returns 5 times whether printing (2+4) succeeded, and
print(2+4) * 5;
returns the same 5*io_success value and tosses it.
See the perlop(1) man page's section on Precedence for more gory
details,
and be sure to use the -w flag to catch things like this.
4.3) What's the difference between dynamic and static (lexical)
scoping?
What are my() and local()?
[NOTE: This question refers to perl5 only. There is no my() in
perl4]
Scoping refers to visibility of variables. A dynamic variable is
created via local() and is just a local value for a global
variable,
whereas a lexical variable created via my() is more what you're
expecting from a C auto. (See also "What's the difference between
deep and shallow binding.") In general, we suggest you use
lexical
variables wherever possible, as they're faster to access and
easier to
understand. The "use strict vars" pragma will enforce that all
variables are either lexical, or full classified by package name.
We
strongly suggest that you develop your code with "use strict;" and
the
-w flag. (When using formats, however, you will still have to use
dynamic variables.) Here's an example of the difference:
$scount = 1; $lcount = 2;
sub foo {
my($i,$j) = @_;
my $scount = 10;
local $lcount = 20;
&bar();
}
sub bar {
print "scount is $scount\en";
print "lcount is $lcount\en";
}
This prints:
scount is 1
lcount is 20
Notice that the variables declared with my() are visible only
within
the scope of the block which names them. They are not visible
outside
of this block, not even in routines or blocks that it calls.
local()
variables, on the other hand, are visible to routines that are
called
from the block where they are declared. Neither is visible after
the
end (the final closing curly brace) of the block at all.
Oh, lexical variables are only available in perl5. Have we
mentioned yet that you might consider upgrading? :-)
4.4) What's the difference between deep and shallow binding?
This only matters when you're making subroutines yourself, at
least
so far. This will give you shallow binding:
{
my $x = time;
$coderef = sub { $x };
}
When you call &$coderef(), it will get whatever dynamic $x happens
to be around when invoked. However, you can get the other
behaviour
this way:
{
my $x = time;
$coderef = eval "sub { \$x }";
}
Now you'll access the lexical variable $x which is set to the
time the subroutine was created. Note that the difference in
these
two behaviours can be considered a bug, not a feature, so you
should
in particular not rely upon shallow binding, as it will likely go
away in the future. See perlref(1).
4.5) How can I manipulate fixed-record-length files?
The most efficient way is using pack and unpack. This is faster
than
using substr. Here is a sample chunk of code to break up and put
back
together again some fixed-format input lines, in this case, from
ps.
# sample input line:
# 15158 p5 T 0:00 perl /mnt/tchrist/scripts/now-what
$ps_t = 'A6 A4 A7 A5 A*';
open(PS, "ps|");
$_ = <PS>; print;
while (<PS>) {
($pid, $tt, $stat, $time, $command) = unpack($ps_t, $_);
for $var ('pid', 'tt', 'stat', 'time', 'command' ) {
print "$var: <", eval "\$$var", ">\n";
}
print 'line=', pack($ps_t, $pid, $tt, $stat, $time, $command),
"\n";
}
4.6) How can I make a file handle local to a subroutine?
You must use the type-globbing *VAR notation. Here is some code
to
cat an include file, calling itself recursively on nested local
include files (i.e. those with #include "file", not #include
<file>):
sub cat_include {
local($name) = @_;
local(*FILE);
local($_);
warn "<INCLUDING $name>\n";
if (!open (FILE, $name)) {
warn "can't open $name: $!\n";
return;
}
while (<FILE>) {
if (/^#\s*include "([^"]*)"/) {
&cat_include($1);
} else {
print;
}
}
close FILE;
}
4.7) How can I call alarm() or usleep() from Perl?
If you want finer granularity than 1 second (as usleep() provides)
and
have itimers and syscall() on your system, you can use the
following.
You could also use select().
It takes a floating-point number representing how long to delay
until
you get the SIGALRM, and returns a floating- point number
representing
how much time was left in the old timer, if any. Note that the C
function uses integers, but this one doesn't mind fractional
numbers.
# alarm; send me a SIGALRM in this many seconds (fractions ok)
# tom christiansen <tchrist@convex.com>
sub alarm {
require 'syscall.ph';
require 'sys/time.ph';
local($ticks) = @_;
local($in_timer,$out_timer);
local($isecs, $iusecs, $secs, $usecs);
local($itimer_t) = 'L4'; # should be &itimer'typedef()
$secs = int($ticks);
$usecs = ($ticks - $secs) * 1e6;
$out_timer = pack($itimer_t,0,0,0,0);
$in_timer = pack($itimer_t,0,0,$secs,$usecs);
syscall(&SYS_setitimer, &ITIMER_REAL, $in_timer, $out_timer)
&& die "alarm: setitimer syscall failed: $!";
($isecs, $iusecs, $secs, $usecs) = unpack($itimer_t,$out_timer);
return $secs + ($usecs/1e6);
}
4.8) How can I do an atexit() or setjmp()/longjmp() in Perl?
(Exception
handling)
Perl's exception-handling mechanism is its eval operator. You
can use eval as setjmp and die as longjmp. Here's an example
of Larry's for timed-out input, which in C is often implemented
using setjmp and longjmp:
$SIG{ALRM} = TIMEOUT;
sub TIMEOUT { die "restart input\n" }
do { eval { &realcode } } while $@ =~ /^restart input/;
sub realcode {
alarm 15;
$ans = <STDIN>;
alarm 0;
}
Here's an example of Tom's for doing atexit() handling:
sub atexit { push(@_exit_subs, @_) }
sub _cleanup { unlink $tmp }
&atexit('_cleanup');
eval <<'End_Of_Eval'; $here = __LINE__;
# as much code here as you want
End_Of_Eval
$oops = $@; # save error message
# now call his stuff
for (@_exit_subs) { &$_() }
$oops && ($oops =~ s/\(eval\) line (\d+)/$0 .
" line " . ($1+$here)/e, die $oops);
You can register your own routines via the &atexit function now.
You
might also want to use the &realcode method of Larry's rather than
embedding all your code in the here-is document. Make sure to
leave
via die rather than exit, or write your own &exit routine and call
that instead. In general, it's better for nested routines to
exit
via die rather than exit for just this reason.
In Perl5, it is easy to set this up because of the automatic
processing
of per-package END functions.
Eval is also quite useful for testing for system dependent
features,
like symlinks, or using a user-input regexp that might otherwise
blowup on you.
4.9) How do I catch signals in perl?
Perl allows you to trap signals using the %SIG associative array.
Using the signals you want to trap as the key, you can assign a
subroutine to that signal. The %SIG array will only contain those
values which the programmer defines. Therefore, you do not have
to
assign all signals. For example, to exit cleanly from a ^C:
$SIG{'INT'} = 'CLEANUP';
sub CLEANUP {
print "\n\nCaught Interrupt (^C), Aborting\n";
exit(1);
}
There are two special "routines" for signals called DEFAULT and
IGNORE.
DEFAULT erases the current assignment, restoring the default value
of
the signal. IGNORE causes the signal to be ignored. In general,
you
don't need to remember these as you can emulate their
functionality
with standard programming features. DEFAULT can be emulated by
deleting the signal from the array and IGNORE can be emulated by
any
undeclared subroutine.
4.10) Why doesn't Perl interpret my octal data octally?
Perl only understands octal and hex numbers as such when they
occur
as literals in your program. If they are read in from somewhere
and
assigned, then no automatic conversion takes place. You must
explicitly use oct() or hex() if you want this kind of thing to
happen.
Actually, oct() knows to interpret both hex and octal numbers,
while
hex only converts hexadecimal ones. For example:
{
print "What mode would you like? ";
$mode = <STDIN>;
$mode = oct($mode);
unless ($mode) {
print "You can't really want mode 0!\n";
redo;
}
chmod $mode, $file;
}
Without the octal conversion, a requested mode of 755 would turn
into 01363, yielding bizarre file permissions of --wxrw--wt.
If you want something that handles decimal, octal and hex input,
you could follow the suggestion in the man page and use:
$val = oct($val) if $val =~ /^0/;
úÿ
4.11) How can I compare two date strings?
If the dates are in an easily parsed, predetermined format, then
you
can break them up into their component parts and call &timelocal
from
the distributed perl library. If the date strings are in
arbitrary
formats, however, it's probably easier to use the getdate program
from
the Cnews distribution, since it accepts a wide variety of dates.
Note
that in either case the return values you will really be comparing
will
be the total time in seconds as returned by time().
Here's a getdate function for perl that's not very efficient; you
can
do better than this by sending it many dates at once or modifying
getdate to behave better on a pipe. Beware the hardcoded
pathname.
sub getdate {
local($_) = shift;
s/-(\d{4})$/+$1/ || s/\+(\d{4})$/-$1/;
# getdate has broken timezone sign reversal!
$_ = `/usr/local/lib/news/newsbin/getdate '$_'`;
chop;
$_;
}
Richard Ohnemus <Rick_Ohnemus@Sterling.COM> actually has a
getdate.y for
use with the Perl yacc. You can get this from ftp.sterling.com
[192.124.9.1] in /local/perl-byacc1.8.1.tar.Z, or send the author
mail
for details.
You might also consider using these:
date.pl - print dates how you want with the sysv +FORMAT
method
date.shar - routines to manipulate and calculate dates
ftp-chat2.shar - updated version of ftpget. includes library and
demo
programs
getdate.shar - returns number of seconds since epoch for any
given
date
ptime.shar - print dates how you want with the sysv +FORMAT
method
You probably want 'getdate.shar'... these and other files can be
ftp'd
from the /pub/perl/scripts directory on ftp.cis.ufl.edu. See the
README
file in the /pub/perl directory for time and the European mirror
site
details.
4.12) How can I find the Julian Day?
Here's an example of a Julian Date function provided by Thomas R.
Kimpton*.
#!/usr/local/bin/perl
@theJulianDate = ( 0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
304, 334
);
#*********************************************************************
***
#**** Return 1 if we are after the leap day in a leap year.
*****
#*********************************************************************
***
sub leapDay
{
my($year,$month,$day) = @_;
if (year % 4) {
return(0);
}
if (!(year % 100)) { # years that are multiples of
100
# are not leap years
if (year % 400) { # unless they are multiples of 400
return(0);
}
}
if (month < 2) {
return(0);
} elsif ((month == 2) && (day < 29)) {
return(0);
} else {
return(1);
}
}
#*********************************************************************
***
#**** Pass in the date, in seconds, of the day you want the
*****
#**** julian date for. If your localtime() returns the year day
*****
#**** return that, otherwise figure out the julian date.
*****
#*********************************************************************
***
sub julianDate
{
my($dateInSeconds) = @_;
my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) =
localtime($dateInSeconds);
if (defined($yday)) {
return($yday+1);
} else {
return($theJulianDate[$mon] + $mday +
&leapDay($year,$mon,$mday));
}
}
print "Today's julian date is: ",&julianDate(time),"\n";
4.13) What's the fastest way to code up a given task in perl?
Post it to comp.lang.perl and ask Tom or Randal a question about
it.
;)
Because Perl so lends itself to a variety of different approaches
for
any given task, a common question is which is the fastest way to
code a
given task. Since some approaches can be dramatically more
efficient
that others, it's sometimes worth knowing which is best.
Unfortunately, the implementation that first comes to mind,
perhaps as
a direct translation from C or the shell, often yields suboptimal
performance. Not all approaches have the same results across
different
hardware and software platforms. Furthermore, legibility must
sometimes be sacrificed for speed.
While an experienced perl programmer can sometimes eye-ball the
code
and make an educated guess regarding which way would be fastest,
surprises can still occur. So, in the spirit of perl programming
being an empirical science, the best way to find out which of
several
different methods runs the fastest is simply to code them all up
and
time them. For example:
$COUNT = 10_000; $| = 1;
print "method 1: ";
($u, $s) = times;
for ($i = 0; $i < $COUNT; $i++) {
# code for method 1
}
($nu, $ns) = times;
printf "%8.4fu %8.4fs\n", ($nu - $u), ($ns - $s);
print "method 2: ";
($u, $s) = times;
for ($i = 0; $i < $COUNT; $i++) {
# code for method 2
}
($nu, $ns) = times;
printf "%8.4fu %8.4fs\n", ($nu - $u), ($ns - $s);
Perl5 includes a new module called Benchmark.pm. You can now
simplify
the code to use the Benchmarking, like so:
use Benchmark;
timethese($count, {
Name1 => '...code for method 1...',
Name2 => '...code for method 2...',
... });
It will output something that looks similar to this:
Benchmark: timing 100 iterations of Name1, Name2...
Name1: 2 secs (0.50 usr 0.00 sys = 0.50 cpu)
Name2: 1 secs (0.48 usr 0.00 sys = 0.48 cpu)
For example, the following code will show the time difference
between
three different ways of assigning the first character of a string
to
a variable:
use Benchmark;
timethese(100000, {
'regex1' => '$str="ABCD"; $str =~ s/^(.)//; $ch = $1',
'regex2' => '$str="ABCD"; $str =~ s/^.//; $ch = $&',
'substr' => '$str="ABCD"; $ch=substr($str,0,1);
substr($str,0,1)="",
});
The results will be returned like this:
Benchmark: timing 100000 iterations of regex1, regex2, substr...
regex1: 11 secs (10.80 usr 0.00 sys = 10.80 cpu)
regex2: 10 secs (10.23 usr 0.00 sys = 10.23 cpu)
substr: 7 secs ( 5.62 usr 0.00 sys = 5.62 cpu)
For more specific tips, see the section on Efficiency in the
``Other Oddments'' chapter at the end of the Camel Book.
4.14) Do I always/never have to quote my strings or use semicolons?
You don't have to quote strings that can't mean anything else in
the
language, like identifiers with any upper-case letters in them.
Therefore, it's fine to do this:
$SIG{INT} = Timeout_Routine;
or
@Days = (Sun, Mon, Tue, Wed, Thu, Fri, Sat, Sun);
but you can't get away with this:
$foo{while} = until;
in place of
$foo{'while'} = 'until';
The requirements on semicolons have been increasingly relaxed.
You no
longer need one at the end of a block, but stylistically, you're
better
to use them if you don't put the curly brace on the same line:
for (1..10) { print }
is ok, as is
@nlist = sort { $a <=> $b } @olist;
but you probably shouldn't do this:
for ($i = 0; $i < @a; $i++) {
print "i is $i\n" # <-- oops!
}
because you might want to add lines later, and anyway, it looks
funny. :-)
4.15) What is variable suicide and how can I prevent it?
Variable suicide is a nasty side effect of dynamic scoping and the
way
variables are passed by reference. If you say
$x = 17;
&munge($x);
sub munge {
local($x);
local($myvar) = $_[0];
...
}
Then you have just clobbered $_[0]! Why this is occurring is
pretty
heavy wizardry: the reference to $x stored in $_[0] was
temporarily
occluded by the previous local($x) statement (which, you're
recall,
occurs at run-time, not compile-time). The work around is simple,
however: declare your formal parameters first:
sub munge {
local($myvar) = $_[0];
local($x);
...
}
That doesn't help you if you're going to be trying to access @_
directly after the local()s. In this case, careful use of the
package
facility is your only recourse.
Another manifestation of this problem occurs due to the magical
nature
of the index variable in a foreach() loop.
@num = 0 .. 4;
print "num begin @num\n";
foreach $m (@num) { &ug }
print "num finish @num\n";
sub ug {
local($m) = 42;
print "m=$m $num[0],$num[1],$num[2],$num[3]\n";
}
Which prints out the mysterious:
num begin 0 1 2 3 4
m=42 42,1,2,3
m=42 0,42,2,3
m=42 0,1,42,3
m=42 0,1,2,42
m=42 0,1,2,3
num finish 0 1 2 3 4
What's happening here is that $m is an alias for each element of
@num.
Inside &ug, you temporarily change $m. Well, that means that
you've
also temporarily changed whatever $m is an alias to!! The only
workaround is to be careful with global variables, using packages,
and/or just be aware of this potential in foreach() loops.
The perl5 static autos via "my" will not have this problem.
4.16) What does "Malformed command links" mean?
This is a bug in 4.035. While in general it's merely a cosmetic
problem, it often comanifests with a highly undesirable
coredumping
problem. Programs known to be affected by the fatal coredump
include
plum and pcops. This bug has been fixed since 4.036. It did not
resurface in 5.000.
4.17) How can I set up a footer format to be used with write()?
While the $^ variable contains the name of the current header
format,
there is no corresponding mechanism to automatically do the same
thing
for a footer. Not knowing how big a format is going to be until
you
evaluate it is one of the major problems.
If you have a fixed-size footer, you can get footers by checking
for
line left on page ($-) before each write, and printing the footer
yourself if necessary.
Another strategy is to open a pipe to yourself, using open(KID, "|-
")
and always write()ing to the KID, who then postprocesses its STDIN
to
rearrange headers and footers however you like. Not very
convenient,
but doable.
4.18) Why does my Perl program keep growing in size?
This is caused by a strange occurance that Larry has dubbed
"feeping
creaturism". Larry is always adding one more feature, always
getting
Perl to handle one more problem. Hence, it keeps growing. Once
you've
worked with perl long enough, you will probably start to do the
same
thing. You will then notice this problem as you see your scripts
becoming larger and larger.
Oh, wait... you meant a currently running program and it's stack
size.
Mea culpa, I misunderstood you. ;) While there may be a real
memory
leak in the Perl source code or even whichever malloc() you're
using,
common causes are incomplete eval()s or local()s in loops.
An eval() which terminates in error due to a failed parsing will
leave
a bit of memory unusable.
A local() inside a loop:
for (1..100) {
local(@array);
}
will build up 100 versions of @array before the loop is done. The
work-around is:
local(@array);
for (1..100) {
undef @array;
}
Larry reports that this behavior is fixed for perl5.
4.19) Can I do RPC in Perl?
Yes, you can, since Perl has access to sockets. An example of the
rup
program written in Perl can be found in the script ruptime.pl at
the
scripts archive on ftp.cis.ufl.edu. I warn you, however, that
it's not
a pretty sight, as it's used nothing from h2ph or c2ph, so
everything is
utterly hard-wired.
4.20) How can I quote a variable to use in a regexp?
From the manual:
$pattern =~ s/(\W)/\\$1/g;
Now you can freely use /$pattern/ without fear of any unexpected
meta-
characters in it throwing off the search. If you don't know
whether a
pattern is valid or not, enclose it in an eval to avoid a fatal
run-
time error.
Perl5 provides a vastly improved way of doing this. Simply use
the
new quotemeta character (\Q) within your variable.
4.21) How can I change the first N letters of a string?
Remember that the substr() function produces an lvalue, that is,
it may
be assigned to. Therefore, to change the first character to an S,
you
could do this:
substr($var,0,1) = 'S';
This assumes that $[ is 0; for a library routine where you can't
know
$[, you should use this instead:
substr($var,$[,1) = 'S';
While it would be slower, you could in this case use a substitute:
$var =~ s/^./S/;
But this won't work if the string is empty or its first character
is a
newline, which "." will never match. So you could use this
instead:
$var =~ s/^[^\0]?/S/;
To do things like translation of the first part of a string, use
substr, as in:
substr($var, $[, 10) =~ tr/a-z/A-Z/;
If you don't know the length of what to translate, something like
this
works:
/^(\S+)/ && substr($_,$[,length($1)) =~ tr/a-z/A-Z/;
úÿ
For some things it's convenient to use the /e switch of the
substitute
operator:
s/^(\S+)/($tmp = $1) =~ tr#a-z#A-Z#, $tmp/e
although in this case, it runs more slowly than does the previous
example.
4.22) Can I use Perl regular expressions to match balanced text?
No, or at least, not by the themselves.
Regexps just aren't powerful enough. Although Perl's patterns
aren't
strictly regular because they do backreferencing (the \1
notation), you
still can't do it. You need to employ auxiliary logic. A simple
approach would involve keeping a bit of state around, something
vaguely like this (although we don't handle patterns on the same
line):
while(<>) {
if (/pat1/) {
if ($inpat++ > 0) { warn "already saw pat1" }
redo;
}
if (/pat2/) {
if (--$inpat < 0) { warn "never saw pat1" }
redo;
}
}
A rather more elaborate subroutine to pull out balanced and
possibly
nested single chars, like ` and ', { and }, or ( and ) can be
found
on convex.com in /pub/perl/scripts/pull_quotes.
4.23) What does it mean that regexps are greedy? How can I get around
it?
The basic idea behind regexps being greedy is that they will match
the
maximum amount of data that they can, sometimes resulting in
incorrect
or strange answers.
For example, I recently came across something like this:
$_="this (is) an (example) of multiple parens";
while ( m#\((.*)\)#g ) {
print "$1\n";
}
This code was supposed to match everything between a set of
parentheses. The expected output was:
is
example
However, the backreference ($1) ended up containing "is) an
(example",
clearly not what was intended.
In perl4, the way to stop this from happening is to use a negated
group. If the above example is rewritten as follows, the results
are
correct:
while ( m#\(([^)]*)\)#g ) {
In perl5 there is a new minimal matching metacharacter, '?'. This
character is added to the normal metacharacters to modify their
behaviour, such as "*?", "+?", or even "??". The example would
now be
written in the following style:
while (m#\((.*?)\)#g )
Hint: This new operator leads to a very elegant method of
stripping
comments from C code:
s:/\*.*?\*/::gs
4.24) How do I use a regular expression to strip C style comments from
a
file?
Since we're talking about how to strip comments under perl5, now
is a
good time to talk about doing it in perl4. The easiest way to
strip
comments in perl4 is to transform the comment close (*/) into
something
that can't be in the string, or is at least extremely unlikely to
be in
the string. I find \256 (the registered or reserved sign, an R
inside
a circle) is fairly unlikely to be used and is easy to remember.
So,
our code looks something like this:
s:\*/:\256:g; # Change all */ to circled R
s:/\*[^\256]*\256::g; # Remove everything from \* to circled R
print;
To ensure that you correctly handle multi-line comments, don't
forget
to set $* to 1, informing perl that it should do multi-line
pattern
matching.
[Untested changes. If it's wrong or you don't understand it,
check
with Jeff. If it's wrong, let me know so I can change it. ]
Jeff Friedl* suggests that the above solution is incorrect. He
says it
will fail on imbedded comments and function proto-typing as well
as on
comments that are part of strings. The following regexp should
handle
everything:
$/ = undef;
$_ = <>;
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|([^/"']*("[^"\\]*(\\[\d\D][^"\\]*)*"[^/
"']*|'[^
'\\]*(\\[\d\D][^'\\]*)*'[^/"']*|/+[^*/][^/"']*)*)#$2#g;
print;
4.25) Why doesn't "local($foo) = <FILE>;" work right?
Well, it does. The thing to remember is that local() provides an
array
context, and that the <FILE> syntax in an array context will read
all the
lines in a file. To work around this, use:
local($foo);
$foo = <FILE>;
You can use the scalar() operator to cast the expression into a
scalar
context:
local($foo) = scalar(<FILE>);
4.26) How can I detect keyboard input without reading it?
You should check out the Frequently Asked Questions list in
comp.unix.* for things like this: the answer is essentially the
same.
It's very system dependent. Here's one solution that works on BSD
systems:
sub key_ready {
local($rin, $nfd);
vec($rin, fileno(STDIN), 1) = 1;
return $nfd = select($rin,undef,undef,0);
}
4.27) How can I read a single character from the keyboard under UNIX
and DOS?
A closely related question to the no-echo question below is how to
input a single character from the keyboard. Again, this is a
system
dependent operation. The following code may or may not help you.
It
should work on both SysV and BSD flavors of UNIX:
$BSD = -f '/vmunix';
if ($BSD) {
system "stty cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", '-icanon',
system "stty", 'eol', "\001";
}
$key = getc(STDIN);
if ($BSD) {
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", 'icanon';
system "stty", 'eol', '^@'; # ascii null
}
print "\n";
You could also handle the stty operations yourself for speed if
you're
going to be doing a lot of them. This code works to toggle cbreak
and echo modes on a BSD system:
sub set_cbreak { # &set_cbreak(1) or &set_cbreak(0)
local($on) = $_[0];
local($sgttyb,@ary);
require 'sys/ioctl.ph';
$sgttyb_t = 'C4 S' unless $sgttyb_t; # c2ph: &sgttyb'typedef()
ioctl(STDIN,&TIOCGETP,$sgttyb) || die "Can't ioctl TIOCGETP: $!";
@ary = unpack($sgttyb_t,$sgttyb);
if ($on) {
$ary[4] |= &CBREAK;
$ary[4] &= ~&ECHO;
} else {
$ary[4] &= ~&CBREAK;
$ary[4] |= &ECHO;
}
$sgttyb = pack($sgttyb_t,@ary);
ioctl(STDIN,&TIOCSETP,$sgttyb) || die "Can't ioctl TIOCSETP: $!";
}
Note that this is one of the few times you actually want to use
the
getc() function; it's in general way too expensive to call for
normal
I/O. Normally, you just use the <FILE> syntax, or perhaps the
read()
or sysread() functions.
For perspectives on more portable solutions, use anon ftp to
retrieve
the file /pub/perl/info/keypress from convex.com.
For DOS systems, Dan Carson <dbc@tc.fluke.COM> reports:
To put the PC in "raw" mode, use ioctl with some magic numbers
gleaned
from msdos.c (Perl source file) and Ralf Brown's interrupt list
(comes
across the net every so often):
$old_ioctl = ioctl(STDIN,0,0); # Gets device info
$old_ioctl &= 0xff;
ioctl(STDIN,1,$old_ioctl | 32); # Writes it back, setting bit 5
Then to read a single character:
sysread(STDIN,$c,1); # Read a single character
And to put the PC back to "cooked" mode:
ioctl(STDIN,1,$old_ioctl); # Sets it back to cooked mode.
So now you have $c. If ord($c) == 0, you have a two byte code,
which
means you hit a special key. Read another byte
(sysread(STDIN,$c,1)),
and that value tells you what combination it was according to this
table:
# PC 2-byte keycodes = ^@ + the following:
# HEX KEYS
# --- ----
# 0F SHF TAB
# 10-19 ALT QWERTYUIOP
# 1E-26 ALT ASDFGHJKL
# 2C-32 ALT ZXCVBNM
# 3B-44 F1-F10
# 47-49 HOME,UP,PgUp
# 4B LEFT
# 4D RIGHT
# 4F-53 END,DOWN,PgDn,Ins,Del
# 54-5D SHF F1-F10
# 5E-67 CTR F1-F10
# 68-71 ALT F1-F10
# 73-77 CTR LEFT,RIGHT,END,PgDn,HOME
# 78-83 ALT 1234567890-=
# 84 CTR PgUp
This is all trial and error I did a long time ago, I hope I'm
reading the
file that worked.
4.28) How can I get input from the keyboard without it echoing to the
screen?
Terminal echoing is generally handled directly by the shell.
Therefore, there is no direct way in perl to turn echoing on and
off.
However, you can call the command "stty [-]echo". The following
will
allow you to accept input without it being echoed to the screen,
for
example as a way to accept passwords (error checking deleted for
brevity):
print "Please enter your password: ";
system("stty -echo");
chop($password=<STDIN>);
print "\n";
system("stty echo");
4.29) Is there any easy way to strip blank space from the
beginning/end of
a string?
Yes, there is. Using the substitution command, you can match the
blanks and replace it with nothing. For example, if you have the
string " String " you can use this:
$_ = " String ";
print ":$_:\n"; # OUTPUT: ": String :"
s/^\s*//;
print ":$_:\n"; # OUTPUT: ":String :"
s/\s*$//;
print ":$_:\n"; # OUTPUT: ":String:"
Unfortunately, there is no simple single statement that will strip
whitespace from both the front and the back in perl4. However, in
perl5 you should be able to say:
s/\s*(.*?)\s*$/$1/;
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 5/5 - External Program Interaction
úÿ(Continued from last message)
grep ($_ eq 'a', keys %ary) is FALSE
See, the whole entry is gone!
5.9) Why don't backticks work as they do in shells?
Several reason. One is because backticks do not interpolate
within
double quotes in Perl as they do in shells.
Let's look at two common mistakes:
$foo = "$bar is `wc $file`"; # WRONG
This should have been:
$foo = "$bar is " . `wc $file`;
But you'll have an extra newline you might not expect. This
does not work as expected:
$back = `pwd`; chdir($somewhere); chdir($back); # WRONG
Because backticks do not automatically eat trailing or embedded
newlines. The chop() function will remove the last character from
a string. This should have been:
chop($back = `pwd`); chdir($somewhere); chdir($back);
You should also be aware that while in the shells, embedding
single quotes will protect variables, in Perl, you'll need
to escape the dollar signs.
Shell: foo=`cmd 'safe $dollar'`
Perl: $foo=`cmd 'safe \$dollar'`;
5.10) How come my converted awk/sed/sh script runs more slowly in
Perl?
The natural way to program in those languages may not make for the
fastest
Perl code. Notably, the awk-to-perl translator produces sub-
optimal code;
see the a2p man page for tweaks you can make.
Two of Perl's strongest points are its associative arrays and its
regular
expressions. They can dramatically speed up your code when
applied
properly. Recasting your code to use them can help a lot.
How complex are your regexps? Deeply nested sub-expressions with
{n,m} or
* operators can take a very long time to compute. Don't use ()'s
unless
you really need them. Anchor your string to the front if you can.
Something like this:
next unless /^.*%.*$/;
runs more slowly than the equivalent:
next unless /%/;
Note that this:
next if /Mon/;
next if /Tue/;
next if /Wed/;
next if /Thu/;
next if /Fri/;
runs faster than this:
next if /Mon/ || /Tue/ || /Wed/ || /Thu/ || /Fri/;
which in turn runs faster than this:
next if /Mon|Tue|Wed|Thu|Fri/;
which runs *much* faster than:
next if /(Mon|Tue|Wed|Thu|Fri)/;
There's no need to use /^.*foo.*$/ when /foo/ will do.
Remember that a printf costs more than a simple print.
Don't split() every line if you don't have to.
Another thing to look at is your loops. Are you iterating through
indexed arrays rather than just putting everything into a hashed
array? For example,
@list = ('abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stv');
for $i ($[ .. $#list) {
if ($pattern eq $list[$i]) { $found++; }
}
First of all, it would be faster to use Perl's foreach mechanism
instead of using subscripts:
foreach $elt (@list) {
if ($pattern eq $elt) { $found++; }
}
Better yet, this could be sped up dramatically by placing the
whole
thing in an associative array like this:
%list = ('abc', 1, 'def', 1, 'ghi', 1, 'jkl', 1,
'mno', 1, 'pqr', 1, 'stv', 1 );
$found += $list{$pattern};
(but put the %list assignment outside of your input loop.)
You should also look at variables in regular expressions, which is
expensive. If the variable to be interpolated doesn't change over
the
life of the process, use the /o modifier to tell Perl to compile
the
regexp only once, like this:
for $i (1..100) {
if (/$foo/o) {
&some_func($i);
}
}
Finally, if you have a bunch of patterns in a list that you'd like
to
compare against, instead of doing this:
@pats = ('_get.*', 'bogus', '_read', '.*exit', '_write');
foreach $pat (@pats) {
if ( $name =~ /^$pat$/ ) {
&some_func();
last;
}
}
If you build your code and then eval it, it will be much faster.
For example:
@pats = ('_get.*', 'bogus', '_read', '.*exit', '_write');
$code = <<EOS
while (<>) {
study;
EOS
foreach $pat (@pats) {
$code .= <<EOS
if ( /^$pat\$/ ) {
&some_func();
next;
}
EOS
}
$code .= "}\n";
print $code if $debugging;
eval $code;
5.11) How can I call my system's unique C functions from Perl?
If these are system calls and you have the syscall() function,
then
you're probably in luck -- see the next question. If you're using
a
POSIX function, and are running perl5, you're also in luck: see
POSIX(3m). For arbitrary library functions, however, it's not
quite so
straight-forward. See "Where can I learn about linking C with
Perl?".
5.12) Where do I get the include files to do ioctl() or syscall()?
[h2ph]
[Note: as of perl5, you probably want to just use h2xs instead, at
least, if your system supports dynamic loading.]
These are generated from your system's C include files using the
h2ph
script (once called makelib) from the Perl source directory. This
will
make files containing subroutine definitions, like &SYS_getitimer,
which
you can use as arguments to your function.
You might also look at the h2pl subdirectory in the Perl source
for how to
convert these to forms like $SYS_getitimer; there are both
advantages and
disadvantages to this. Read the notes in that directory for
details.
In both cases, you may well have to fiddle with it to make these
work; it
depends how funny-looking your system's C include files happen to
be.
If you're trying to get at C structures, then you should take a
look
at using c2ph, which uses debugger "stab" entries generated by
your
BSD or GNU C compiler to produce machine-independent perl
definitions
for the data structures. This allows to you avoid hardcoding
structure layouts, types, padding, or sizes, greatly enhancing
portability. c2ph comes with the perl distribution. On an SCO
system, GCC only has COFF debugging support by default, so you'll
have
to build GCC 2.1 with DBX_DEBUGGING_INFO defined, and use -gstabs
to
get c2ph to work there.
See the file /pub/perl/info/ch2ph on convex.com via anon ftp
for more traps and tips on this process.
5.13) Why do setuid Perl scripts complain about kernel problems?
This message:
YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!
FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND
UNDUMP!
is triggered because setuid scripts are inherently insecure due to
a
kernel bug. If your system has fixed this bug, you can compile
Perl
so that it knows this. Otherwise, create a setuid C program that
just
execs Perl with the full name of the script. Here's what the
perldiag(1) man page says about this message:
YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!
(F) And you probably never will, since you probably don't have
the sources to your kernel, and your vendor probably doesn't
give a rip about what you want. Your best bet is to use the
wrapsuid script in the eg directory to put a setuid C
wrapper
around your script.
5.14) How do I open a pipe both to and from a command?
In general, this is a dangerous move because you can find yourself
in a
deadlock situation. It's better to put one end of the pipe to a
file.
For example:
# first write some_cmd's input into a_file, then
open(CMD, "some_cmd its_args < a_file |");
while (<CMD>) {
# or else the other way; run the cmd
open(CMD, "| some_cmd its_args > a_file");
while ($condition) {
print CMD "some output\n";
# other code deleted
}
close CMD || warn "cmd exited $?";
# now read the file
open(FILE,"a_file");
while (<FILE>) {
If you have ptys, you could arrange to run the command on a pty
and
avoid the deadlock problem. See the chat2.pl package in the
distributed library for ways to do this.
At the risk of deadlock, it is theoretically possible to use a
fork, two pipe calls, and an exec to manually set up the two-way
pipe. (BSD system may use socketpair() in place of the two pipes,
but this is not as portable.) The open2 library function
distributed
with the current perl release will do this for you.
It assumes it's going to talk to something like adb, both writing
to
it and reading from it. This is presumably safe because you
"know"
that commands like adb will read a line at a time and output a
line at
a time. Programs like sort that read their entire input stream
first,
however, are quite apt to cause deadlock.
There's also an open3.pl library that handles this for stderr as
well.
5.15) How can I capture STDERR from an external command?
There are three basic ways of running external commands:
system $cmd;
$output = `$cmd`;
open (PIPE, "cmd |");
In the first case, both STDOUT and STDERR will go the same place
as
the script's versions of these, unless redirected. You can always
put
them where you want them and then read them back when the system
returns. In the second and third cases, you are reading the
STDOUT
*only* of your command. If you would like to have merged STDOUT
and
STDERR, you can use shell file-descriptor redirection to dup
STDERR to
STDOUT:
$output = `$cmd 2>&1`;
open (PIPE, "cmd 2>&1 |");
Another possibility is to run STDERR into a file and read the file
later, as in
$output = `$cmd 2>some_file`;
open (PIPE, "cmd 2>some_file |");
Here's a way to read from both of them and know which descriptor
you got each line from. The trick is to pipe only STDERR through
sed, which then marks each of its lines, and then sends that
back into a merged STDOUT/STDERR stream, from which your Perl
program
then reads a line at a time:
open (CMD,
"cmd args | sed 's/^/STDOUT:/' |");
while (<CMD>) {
if (s/^STDOUT://) {
print "line from stdout: ", $_;
} else {
print "line from stdeff: ", $_;
}
}
Be apprised that you *must* use Bourne shell redirection syntax in
backticks, not csh! For details on how lucky you are that perl's
system() and backtick and pipe opens all use Bourne shell, fetch
the
file from convex.com called /pub/csh.whynot -- and you'll be glad
that
perl's shell interface is the Bourne shell.
There's an &open3 routine out there which was merged with &open2
in
perl5 production.
5.16) Why doesn't open return an error when a pipe open fails?
These statements:
open(TOPIPE, "|bogus_command") || die ...
open(FROMPIPE, "bogus_command|") || die ...
will not fail just for lack of the bogus_command. They'll only
fail if the fork to run them fails, which is seldom the problem.
If you're writing to the TOPIPE, you'll get a SIGPIPE if the child
exits prematurely or doesn't run. If you are reading from the
FROMPIPE, you need to check the close() to see what happened.
If you want an answer sooner than pipe buffering might otherwise
afford you, you can do something like this:
$kid = open (PIPE, "bogus_command |"); # XXX: check defined($kid)
(kill 0, $kid) || die "bogus_command failed";
This works fine if bogus_command doesn't have shell metas in it,
but
if it does, the shell may well not have exited before the kill 0.
You
could always introduce a delay:
$kid = open (PIPE, "bogus_command </dev/null |");
sleep 1;
(kill 0, $kid) || die "bogus_command failed";
but this is sometimes undesirable, and in any event does not
guarantee
correct behavior. But it seems slightly better than nothing.
Similar tricks can be played with writable pipes if you don't wish
to
catch the SIGPIPE.
5.17) Why can't my perl program read from STDIN after I gave it ^D
(EOF) ?
Because some stdio's set error and eof flags that need clearing.
Try keeping around the seekpointer and go there, like this:
$where = tell(LOG);
seek(LOG, $where, 0);
If that doesn't work, try seeking to a different part of the file
and
then back. If that doesn't work, try seeking to a different part
of
the file, reading something, and then seeking back. If that
doesn't
work, give up on your stdio package and use sysread. You can't
call
stdio's clearerr() from Perl, so if you get EINTR from a signal
handler, you're out of luck. Best to just use sysread() from the
start for the tty.
5.18) How can I translate tildes in a filename?
Perl doesn't expand tildes -- the shell (ok, some shells) do.
The classic request is to be able to do something like:
open(FILE, "~/dir1/file1");
open(FILE, "~tchrist/dir1/file1");
which doesn't work. (And you don't know it, because you
did a system call without an "|| die" clause! :-)
If you *know* you're on a system with the csh, and you *know*
that Larry hasn't internalized file globbing, then you could
get away with
$filename = <~tchrist/dir1/file1>;
but that's pretty iffy.
A better way is to do the translation yourself, as in:
$filename =~ s#^~(\w+)(/.*)?$#(getpwnam($1))[7].$2#e;
More robust and efficient versions that checked for error
conditions,
handed simple ~/blah notation, and cached lookups are all
reasonable
enhancements.
5.19) How can I convert my shell script to Perl?
Larry's standard answer is to send it through the shell to perl
filter,
otherwise known at tchrist@perl.com. Contrary to popular belief,
Tom
Christiansen isn't a real person. He is actually a highly
advanced
artificial intelligence experiment written by a graduate student
at the
University of Colorado. Some of the earlier tasks he was
programmed to
perform included:
* monitor comp.lang.perl and collect statistics on which questions
were asked with which frequency and to respond to them with stock
answers. Tom's programming has since outgrown this paltry task,
and it has been assigned to an undergraduate student from the
University of Florida. After all, we all know that student from
UF aren't able to do much more than documentation anyway. ;-)
* convert shell programs to perl programs
Actually, there is no automatic machine translator. Even if there
were, you wouldn't gain a lot, as most of the external programs
would
still get called. It's the same problem as blind translation into
C:
you're still apt to be bogged down by exec()s. You have to
analyze
the dataflow and algorithm and rethink it for optimal speedup.
It's
úÿ
not uncommon to see one, two, or even three orders of magnitude of
speed difference between the brute-force and the recoded
approaches.
5.20) Can I use Perl to run a telnet or ftp session?
Sure, you can connect directly to them using sockets, or you can
run a
session on a pty. In either case, Randal's chat2 package, which
is
distributed with the perl source, will come in handly. It address
much the same problem space as Don Libes's expect package does.
Two
examples of using managing an ftp session using chat2 can be found
on
convex.com in /pub/perl/scripts/ftp-chat2.shar .
Caveat lector: chat2 is documented only by example, may not run on
System V systems, and is subtly machine dependent both in its
ideas
of networking and in pseudottys.
Randal also has code showing an example socket session for
handling the
telnet protocol. You might nudge him for a copy.
Gene Spafford* has a nice ftp library package that will help with
ftp.
5.21) Why do I somestimes get an "Arguments too long" when I use <*>?
As of perl4.036, there is a certain amount of globbing that is
passed
out to the shell and not handled internally. The following code
(which
will, roughly, emulate "chmod 0644 *")
while (<*>) {
chmod 0644, $_;
}
is the equivalent of
open(FOO, "echo * | tr -s ' \t\r\f' '\\012\\012\\012\\012'|");
while (<FOO>) {
chop;
chmod 0644, $_;
}
Until globbing is built into Perl, you will need to use some form
of
non-globbing work around.
Something like the following will work:
opendir(DIR,'.');
chmod 0644, grep(/\.c$/, readdir(DIR));
closedir(DIR);
This example is taken directly from "Programming Perl" page 78.
If you've installed tcsh as /bin/csh, you'll never have this
problem.
5.22) How do I do a "tail -f" in Perl?
Larry says that the solution is to put a call to seek in yourself.
First try
seek(GWFILE, 0, 1);
If that doesn't work (depends on your stdio implementation), then
you need something more like this:
for (;;) {
for ($curpos = tell(GWFILE); $_ = <GWFILE>; $curpos = tell(GWFILE)) {
# search for some stuff and put it into files
}
sleep for a while
seek(GWFILE, $curpos, 0);
}
5.23) Is there a way to hide perl's command line from programs such as
"ps"?
Generally speaking, if you need to do this you're either using
poor
programming practices or are far too paranoid for your own good.
If you
need to do this to hide a password being entered on the command
line,
recode the program to read the password from a file or to prompt
for
it. (see question 4.24) Typing a password on the command line is
inherently insecure as anyone can look over your shoulder to see
it.
If you feel you really must overwrite the command line and hide
it, you
can assign to the variable "$0". For example:
#!/usr/local/bin/perl
$0 = "Hidden from prying eyes";
open(PS, "ps") || die "Can't PS: $!";
while (<PS>) {
next unless m/$$/;
print
}
It should be noted that some OSes, like Solaris 2.X, read directly
from
the kernel information, instead of from the program's stack, and
hence
don't allow you to change the command line.
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 5/5 - External Program Interaction
Message-ID: <perl-faq/part5_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 5/5 - External Program Interaction
Supersedes: <perl-faq/part5_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:48 GMT
Organization: none
Lines: 883
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part5_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39240 comp.answers:8357
news.answers:32284
Archive-name: perl-faq/part5
Version: $Id: part5,v 2.2 1994/11/07 18:06:59 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to the following questions about Array,
Shell
and External Program Interactions with Perl:
5.1) What is the difference between $array[1] and @array[1]?
Always make sure to use a $ for single values and @ for multiple
ones.
Thus element 2 of the @foo array is accessed as $foo[2], not
@foo[2],
which is a list of length one (not a scalar), and is a fairly
common
novice mistake. Sometimes you can get by with @foo[2], but it's
not really doing what you think it's doing for the reason you
think
it's doing it, which means one of these days, you'll shoot
yourself
in the foot; ponder for a moment what these will really do:
@foo[0] = `cmd args`;
@foo[2] = <FILE>;
Just always say $foo[2] and you'll be happier.
This may seem confusing, but try to think of it this way: you use
the
character of the type which you *want back*. You could use
@foo[1..3] for
a slice of three elements of @foo, or even @foo{A,B,C} for a slice
of
of %foo. This is the same as using ($foo[1], $foo[2], $foo[3])
and
($foo{A}, $foo{B}, $foo{C}) respectively. In fact, you can even
use
lists to subscript arrays and pull out more lists, like @foo[@bar]
or
@foo{@bar}, where @bar is in both cases presumably a list of
subscripts.
5.2) How can I make an array of arrays or other recursive data types?
In Perl5, it's quite easy to declare these things. For example
@A = (
[ 'ww' .. 'xx' ],
[ 'xx' .. 'yy' ],
[ 'yy' .. 'zz' ],
[ 'zz' .. 'zzz' ],
);
And now reference $A[2]->[0] to pull out "yy". These may also
nest
and mix with tables:
%T = (
key0, { k0, v0, k1, v1 },
key1, { k2, v2, k3, v3 },
key2, { k2, v2, k3, [ 0, 'a' .. 'z' ] },
);
Allowing you to reference $T{key2}->{k3}->[3] to pull out 'c'.
Perl4 is infinitely more difficult. Remember that Perl[0..4]
isn't
about nested data structures. It's about flat ones, so if you're
trying to do this, you may be going about it the wrong way or
using the
wrong tools. You might try parallel arrays with common
subscripts.
But if you're bound and determined, you can use the multi-
dimensional
array emulation of $a{'x','y','z'}, or you can make an array of
names
of arrays and eval it.
For example, if @name contains a list of names of arrays, you can
get
at a the j-th element of the i-th array like so:
$ary = $name[$i];
$val = eval "\$$ary[$j]";
or in one line
$val = eval "\$$name[$i][\$j]";
You could also use the type-globbing syntax to make an array of
*name
values, which will be more efficient than eval. Here @name hold a
list
of pointers, which we'll have to dereference through a temporary
variable.
For example:
{ local(*ary) = $name[$i]; $val = $ary[$j]; }
In fact, you can use this method to make arbitrarily nested data
structures. You really have to want to do this kind of thing
badly to
go this far, however, as it is notationally cumbersome.
Let's assume you just simply *have* to have an array of arrays of
arrays. What you do is make an array of pointers to arrays of
pointers, where pointers are *name values described above. You
initialize the outermost array normally, and then you build up
your
pointers from there. For example:
@w = ( 'ww' .. 'xx' );
@x = ( 'xx' .. 'yy' );
@y = ( 'yy' .. 'zz' );
@z = ( 'zz' .. 'zzz' );
@ww = reverse @w;
@xx = reverse @x;
@yy = reverse @y;
@zz = reverse @z;
Now make a couple of arrays of pointers to these:
@A = ( *w, *x, *y, *z );
@B = ( *ww, *xx, *yy, *zz );
And finally make an array of pointers to these arrays:
@AAA = ( *A, *B );
To access an element, such as AAA[i][j][k], you must do this:
local(*foo) = $AAA[$i];
local(*bar) = $foo[$j];
$answer = $bar[$k];
Similar manipulations on associative arrays are also feasible.
You could take a look at recurse.pl package posted by Felix Lee*,
which
lets you simulate vectors and tables (lists and associative
arrays) by
using type glob references and some pretty serious wizardry.
In C, you're used to creating recursive datatypes for operations
like
recursive decent parsing or tree traversal. In Perl, these
algorithms
are best implemented using associative arrays. Take an array
called
%parent, and build up pointers such that $parent{$person} is the
name
of that person's parent. Make sure you remember that
$parent{'adam'}
is 'adam'. :-) With a little care, this approach can be used to
implement general graph traversal algorithms as well.
5.3) How do I make an array of structures containing various data
types?
The best way to do this is to use an associative array to model
your
structure, then either a regular array (AKA list) or another
associative array (AKA hash, table, or hash table) to store it.
%foo = (
'field1' => "value1",
'field2' => "value2",
'field3' => "value3",
...
);
...
@all = ( \%foo, \%bar, ... );
print $all[0]{'field1'};
Or even
@all = (
{
'field1' => "value1",
'field2' => "value2",
'field3' => "value3",
...
},
{
'field1' => "value1",
'field2' => "value2",
'field3' => "value3",
...
},
...
)
See perlref(1).
5.4) How can I extract just the unique elements of an array?
There are several possible ways, depending on whether the
array is ordered and you wish to preserve the ordering.
a) If @in is sorted, and you want @out to be sorted:
$prev = 'nonesuch';
@out = grep($_ ne $prev && (($prev) = $_), @in);
This is nice in that it doesn't use much extra memory,
simulating uniq's behavior of removing only adjacent
duplicates.
b) If you don't know whether @in is sorted:
undef %saw;
@out = grep(!$saw{$_}++, @in);
c) Like (b), but @in contains only small integers:
@out = grep(!$saw[$_]++, @in);
d) A way to do (b) without any loops or greps:
undef %saw;
@saw{@in} = ();
@out = sort keys %saw; # remove sort if undesired
e) Like (d), but @in contains only small positive integers:
undef @ary;
@ary[@in] = @in;
@out = sort @ary;
5.5) How can I tell whether an array contains a certain element?
There are several ways to approach this. If you are going to make
this query many times and the values are arbitrary strings, the
fastest way is probably to invert the original array and keep an
associative array lying about whose keys are the first array's
values.
@blues = ('turquoise', 'teal', 'lapis lazuli');
undef %is_blue;
for (@blues) { $is_blue{$_} = 1; }
Now you can check whether $is_blue{$some_color}. It might have
been
a good idea to keep the blues all in an assoc array in the first
place.
If the values are all small integers, you could use a simple
indexed array. This kind of an array will take up less space:
@primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
undef @is_tiny_prime;
for (@primes) { $is_tiny_prime[$_] = 1; }
Now you check whether $is_tiny_prime[$some_number].
If the values in question are integers instead of strings, you can
save
quite a lot of space by using bit strings instead:
@articles = ( 1..10, 150..2000, 2017 );
undef $read;
grep (vec($read,$_,1) = 1, @articles);
Now check whether vec($read,$n,1) is true for some $n.
5.6) How do I sort an associative array by value instead of by key?
You have to declare a sort subroutine to do this, or use an inline
function. Let's assume you want an ASCII sort on the values of
the
associative array %ary. You could do so this way:
foreach $key (sort by_value keys %ary) {
print $key, '=', $ary{$key}, "\n";
}
sub by_value { $ary{$a} cmp $ary{$b}; }
If you wanted a descending numeric sort, you could do this:
sub by_value { $ary{$b} <=> $ary{$a}; }
You can also inline your sort function, like this, at least if
you have a relatively recent patchlevel of perl4 or are running
perl5:
foreach $key ( sort { $ary{$b} <=> $ary{$a} } keys %ary ) {
print $key, '=', $ary{$key}, "\n";
}
If you wanted a function that didn't have the array name hard-
wired
into it, you could so this:
foreach $key (&sort_by_value(*ary)) {
print $key, '=', $ary{$key}, "\n";
}
sub sort_by_value {
local(*x) = @_;
sub _by_value { $x{$a} cmp $x{$b}; }
sort _by_value keys %x;
}
If you want neither an alphabetic nor a numeric sort, then you'll
have to code in your own logic instead of relying on the built-in
signed comparison operators "cmp" and "<=>".
Note that if you're sorting on just a part of the value, such as a
piece you might extract via split, unpack, pattern-matching, or
substr, then rather than performing that operation inside your
sort
routine on each call to it, it is significantly more efficient to
build a parallel array of just those portions you're sorting on,
sort
the indices of this parallel array, and then to subscript your
original
array using the newly sorted indices. This method works on both
regular and associative arrays, since both @ary[@idx] and
@ary{@idx}
make sense. See page 245 in the Camel Book on "Sorting an Array
by a
Computable Field" for a simple example of this.
5.7) How can I know how many entries are in an associative array?
While the number of elements in a @foobar array is simply @foobar
when
used in a scalar, you can't figure out how many elements are in an
associative array in an analogous fashion. That's because %foobar
in
a scalar context returns the ratio (as a string) of number of
buckets
filled versus the number allocated. For example, scalar(%ENV)
might
return "20/32". While perl could in theory keep a count, this
would
break down on associative arrays that have been bound to dbm
files.
However, while you can't get a count this way, one thing you *can*
use
it for is to determine whether there are any elements whatsoever
in
the array, since "if (%table)" is guaranteed to be false if
nothing
has ever been stored in it.
As of perl4.035, you can says
$count = keys %ARRAY;
keys() when used in a scalar context will return the number of
keys,
rather than the keys themselves.
5.8) What's the difference between "delete" and "undef" with %arrays?
Pictures help... here's the %ary table:
keys values
+------+------+
| a | 3 |
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
And these conditions hold
$ary{'a'} is true
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is true
exists $ary{'a'} is true (perl5 only)
grep ($_ eq 'a', keys %ary) is true
If you now say
undef $ary{'a'}
your table now reads:
keys values
+------+------+
| a | undef|
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
and these conditions now hold; changes in caps:
$ary{'a'} is FALSE
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is FALSE
exists $ary{'a'} is true (perl5 only)
grep ($_ eq 'a', keys %ary) is true
Notice the last two: you have an undef value, but a defined key!
Now, consider this:
delete $ary{'a'}
your table now reads:
keys values
+------+------+
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
and these conditions now hold; changes in caps:
$ary{'a'} is false
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is false
exists $ary{'a'} is FALSE (perl5 only)
Version: $Id: perl-intro,v 2.2 1994/11/07 18:05:12 spp Exp spp $
Posting-Frequency: bi-weekly
Archive-name: perl-faq/part1
Version: $Id: part1,v 2.3 1994/11/07 18:05:23 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to general information and availability
questions. The following questions are answered in this posting:
1.1) What is Perl?
Perl is a compiled scripting language written by Larry Wall*.
Here's the beginning of the description from the perl(1) man page:
Perl is an interpreted language optimized for scanning arbi-
trary text files, extracting information from those text
files, and printing reports based on that information. It's
also a good language for many system management tasks. The
language is intended to be practical (easy to use, effi-
cient, complete) rather than beautiful (tiny, elegant,
minimal). It combines (in the author's opinion, anyway)
some of the best features of C, sed, awk, and sh, so people
familiar with those languages should have little difficulty
with it. (Language historians will also note some vestiges
of csh, Pascal, and even BASIC-PLUS.) Expression syntax
corresponds quite closely to C expression syntax. Unlike
most Unix utilities, perl does not arbitrarily limit the
size of your data--if you've got the memory, perl can slurp
in your whole file as a single string. Recursion is of
unlimited depth. And the hash tables used by associative
arrays grow as necessary to prevent degraded performance.
Perl uses sophisticated pattern matching techniques to scan
large amounts of data very quickly. Although optimized for
scanning text, perl can also deal with binary data, and can
make dbm files look like associative arrays (where dbm is
available). Setuid perl scripts are safer than C programs
through a dataflow tracing mechanism which prevents many
stupid security holes. If you have a problem that would
ordinarily use sed or awk or sh, but it exceeds their capa-
bilities or must run a little faster, and you don't want to
write the silly thing in C, then perl may be for you. There
are also translators to turn your sed and awk scripts into
perl scripts. OK, enough hype.
1.2) What are perl4 and perl5, are there any differences?
Perl4 and perl5 are different versions of the language. Perl4 was
the
previous release, and perl5 is "Perl: The Next Generation."
Perl5 is, essentially, a complete rewrite of the perl source code
from the ground up. It has been modularized, object oriented,
tweaked, trimmed, and optimized until it almost doesn't look like
the old code. However, the interface is mostly the same, and
compatibility with previous releases is very high.
1.3) What features does perl5 provide over perl4?
If you get the newest source (from any of the main FTP sites), you
will
find a directory full of man pages (possibly to be installed as
section
1p and 3pm) that discuss the differences, new features, old
incompatibilies and much more. Here, however, are some highlights
as
to the new feature and old incompatibilites.
* Enhanced Usability: Perl code can now be written in a much more
legible style. Regular expressions have been enhanced to allow
minimal matches, conditionals, and much more. Cryptic variable
names (although still supported) have been aliased to new
nmemonics, using the "English" module, allowing old scripts to
run
and new scripts to be readable. Error messages and optional
warnings are more informative and will catch many common
mistakes.
See the perldiag(1) man page, which contains pithy prose from
Larry
Wall* on each and every possible muttering perl might spout at
you.
* Simplified Grammar: The new yacc grammar is one half the size
of
the old one. Many of the arbitrary grammer rules have been
regularized. The number of reserved words has been cut by 2/3.
* Lexical Scoping: Perl variables may now be declared within a
lexical scope, similar to C's "auto" variables. This is a
great improvement on efficiency and contributes to better
privacy. See the my() entry in perlfunc(1).
* Arbitrarily nested data structures: Full fledged
multidimensional
arrays. Any scalar value, including an array element, may now
contain a reference to any other variable or subroutine.
Easily created anonymous variables and subroutines. See
perlref(1).
* Modularity and Reusability: The Perl library is now defined in
terms of modules which can be easily shared among various
packages. Packages can import any or all of a module's
published interface. See perlmod(1), perlsub(1), and
Exporter(3pm).
* Object-oriented programming: A package can function as a class.
Dynamic multiple inheritance and virtual methods are supported
in a straight-forward manner with little new syntax. Filehandles
are now treated as objects. See perlobj(1), perlmod(1), and
FileHandle(3pm).
* Embeddible and Extensible: Perl can be easily embedded in C/C++
approlications, and can either call or be called by your
routines through a documented interface. The XS preprocessor
is provided to make it easy to glue your C/C++ routines into
Perl. Dynamic loading of modules is supported. See perlapi(1),
perlcall(1), and DynaLoader(3pm).
* POSIX compliant: A major new module is the POSIX module, which
provides access to all available POSIX routines and definitions.
Seee POSIX(3pm).
* Package constructors and destructors: The new BEGIN and END
blocks
provide means to capture control as a package is being compiled
and
after the program exits. As a degenerate case, they work just
like
awk's BEGIN and END when you use the -p or -n switches. See
perlmod(1).
* Multiple simultaneous DBM implementations: A perl program now
has
access to DBM, NDBM, SDBM, GDBM and Berkeley DB files in the same
script. The dbmopen interface has been generalized to allow any
variable to be tied to an object class which defines its access
methods. tie/untie now preferable to dbmopen/dbmclose. See the
tie() entry in perlfunc(1) and the DB_File(3pm) man pages.
* Subroutine definitions may now be autoloaded: The AUTOLOAD
mechanism
allows any arbitrary semantics to undefined subroutine calls.
See
the section on Autoloading in the perlsub(1) manpage.
* Regular Expression Enhancements: Qualifiers may be followed by
a "?"
to signify that they should be non-greedy. A "?" directly after
an opening paren indicates non backreference grouping and the next
character determines the purpose of the match (?:a|b|c) will match
any of a b or c without producing a backreference, (?=stuff) does
a non-eating look ahead to assure that the next thing is stuff,
(?!nonsense) looks ahead to assure that the next thing must not
be "nonsense". Embedded whitespace and comments for readability.
A consistent extensibility mechanism has been added that is
upwardly compatible with all old regexps. Variables may now be
interpoled literally into a pattern with \Q or the quotemeta
fuction, which works like \U but backwhacks non-alphanumerics.
New m and s "flags" for pattern matching force multi- or
single-line matching. The "s" makes "." match "\n". \A and
\Z anchor matches to the beginning and end of a string and ignore
multiline semantics. \G matches where the previous m//g or s///g
left off.
* The -w (warnings) switch is much more informative.
* References and Objects (see t/op/ref.t) for examples.
* => is a synonum for comma and helps group paired arguments, such
as initializers for associative arrays and named arguments to
subroutines.
* All functions, even predeclared subroutines, are treated as list
operators or unary operators. Parens are optional.
* Flattened interpreter: Compare perl4's eval.c with perl5's
pp.c.
Compare perl4's 900 line interpreter look with perl5's one line.
* eval is now treated like a subroutine call, meaning (among other
things) you can return from it.
* format value lists may be spread over multiple lines with a do
{}
block.
* flags on the #! line are interpreted even if the script wasn't
invoked directly.
* ?: is now an lvalue.
* list context now propogates to the right side of && and ||, and
as the 2nd and 3rd arguments of ?:
* preferred package delimeter now :: rather than '.
* new "and" and "or" operators, like && and || but with a lower
precedence than comma, so they work better with list operators.
* New functions abs(), chr(), uc(), ucfirst(), lc(), and lcfirst()
* require(number) checks to see that the version is at least that
version
* qw//, which is equivalent to split(' ', q//)
* assignment of a reference to a glob replaces the single element
of the glob corresponding to the reference type:
*foo = \$bar, * foo = \&bletch;
* filehandle methods are supported:
output_autoflush STDOUT 1;
* Autoload stubs can now call the replacement subroutine with
goto &realsub.
* Subroutines can be defined lazily in any package by declaring
an AUTOLOAD routine, which will be called if a non-existant
subroutine is called in that package.
* "use" and "no" subsume many feautres. "use Module LIST" is
short for "BEGIN { require Module; import Module LIST }"
"no" is identical, except that it calls "unimport" instead.
"use integer" and variations of "use strict [vars,refs,subs]"
were implemented through new modules.
(Thanks to Tom Christiansen* for this section)
1.4) Where can I get docs on perl5?
The complete perl documentation is available with the Perl
distribution, or can be accessed from the following sites.
Note that the PerlDoc ps file is 240 pages long!!
http://www.metronet.com/0/perlinfo/perl5/manual/perl.html
ftp://ftp.uu.net/languages/perl/PerlDoc.ps.gz
ftp://prep.ai.mit.edu/pub/gnu/PerlDoc.ps.gz
ftp://ftp.cbi.tamucc.edu/pub/duff/Perl/PerlDoc.ps.gz
ftp://www.metronet.com/pub/perlinfo/perl5/manual/PerlDoc.ps.gz
http://web.nexor.co.uk/perl/perl.html (Europe)
ftp://ftp.zrz.tu-berlin.de/pub/unix/perl/PerlDoc.ps.gz
(Europe)
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/PerlDoc.ps.gz
(Europe)
ftp://sungear.mame.mu.oz.au/pub/perl/doc/PerlDoc.ps.gz (Oz)
1.5) Will perl5 break my perl4 scripts?
In general, no. However, certain bad old practices have become
highly
frowned upon. The following are the most important of the known
incompatibilies between perl4 and perl5. See perltrap(1) for more
details.
* "@" ***ALWAYS*** interpolate in double quoted strings. Non-
array
"@"s must be escaped:
Mail("foo@bar.com") needs to be
Mail("foo\@bar.com");
The compiler catches this.
* "open FILE || die" needs to be "open(FILE) || die". The
compiler
forgives you for this, but won't stop complaining until you fix
it.
* Barewords are no longer (necessarily) strings: they will
actually
call the function (if it existed when that code was compiled)
instead of returning a string of that value. Check your
signal handlers. The 'use strict subs' pragma (see strict(3pm))
will help you with this.
* "shift @x + 20" needs to be "shift(@x) + 20" because of
precedence,
and likewise "$y = scalar keys %foo + 30" needs to be instead
"$y = scalar keys(%foo) + 30".
* The internal symbol table is called %{PACKAGE::} for any given
package. It used to be %{_PACKAGE}.
* You may no longer (attempt to) write to read-only variables,
like $1,
or assign to a substr() past the end of a string.
* Various deprecated practices elicit warning messages.
1.6) When will Perl stabilize?
When asked at what point the Perl code would be frozen, Larry answere:
Part of the redesign of Perl is to *allow* us to more or less
freeze
the language itself. It won't totally freeze, of course, but I
think
the rate of change of the core of the language is asymptotically
approaching 0. In fact, as time goes on, now that we have an
official
extension mechanism, some of the things that are currently in the
core
of the language may move out (transparently) as extensions. This
has
already happened to dbmopen().
I've also been continuously reminding myself of what Henry Spencer
calls "second system syndrome", in which everything under the sun
gets
added, resulting in a colossal kludge, like OS 360. You'll find
that
the new features in Perl 5 are all pretty minimalistic. The
object-oriented features in particular added only one new piece of
syntax, a C++-style method call.
: The whole idea
: Perl is to be a fast text-processing, system-maintenance, zero-
startup
: time language. If it gets to be so large and complicated that it
isn't
: fast-running and easy to use, it won't be to anyone's benefit.
My motto from the start has been, "If it ain't broke, don't fix
it."
I've been trying very hard not to remove those features from Perl
that
make it what it is. At the same time, a lot of streamlining has
gone
into the syntax. The new yacc file is about half the size of the
old
one, and the number of official reserved words has been cut by
2/3.
All built-in functions have been unified (dualified?) as either
list
operators or unary operators.
: I really like a lot of the features in Perl, but in order for
Perl to
: be useful on a long term basis, those features have to stay put.
I
: bought the Camel book less than a year ago and it sounds like
within
: another year it will be obsolete.
The parts of Perl that the Camel book covers have not changed all
that
much. Most old scripts still run. Many scripts from Perl version
1.0
still run. We'll certainly be revising the Camel, but the new man
pages are split up such that it's pretty easy to ferret out the
new
info when you want it.
We did break a few misfeatures in going to Perl 5. It seemed like
the
first and last chance to do so. There's a list of the
incompatibilities in the documentation.
: Not only is it a lot of work to recompile Perl
: on 20+ machines periodically, but it's hard to write scripts
that are
: useful in the long term if the guts of the language keep
changing.
: (And if I keep having to buy new books. I keep hearing about new
: features of Perl 5 that aren't documented in any of the perl 5
: documentation that *I* can find.)
I think you'll find a lot of folks who think that 4.036 has been a
pretty stable platform.
Perl 5 is a special case. I've been working on it for years.
(This is
part of the reason 4.036 has been so stable!) There are many
changes,
most of them for the better, I hope. I don't expect the
transition to
be without pain. But that's why I stuck numbered versions out in
your
bin directory, so that you can upgrade piecemeal if you like. And
that's why I made the -w switch warn about many of the
incompatibilities.
And overriding all that, I've tried to keep it so that you don't
have
to know much about the new stuff to use the old stuff. You can
upgrade
your *knowledge* piecemeal too.
The extension mechanism is designed to take over most of the
evolutionary role from now on. And it's set up so that, if you
don't
have a particular extension, you know it right up at the front.
: Are there any plans to write a Perl compiler? While interpreted
Perl
: is great for many applications, it would also be cool to be able
to
: precompile many scripts. (Yes, I know you can undump things, but
: undump isn't provided with Perl and I haven't found a copy.) The
: creation of a perl library and dynamically-loadable modules
seems
: like a step in that direction.
Yes, part of the design of Perl 5 was to make it *possible* to
write a
compiler for it. It could even be done as an extension module, I
suppose. Anyone looking for a master's thesis topic?
In summary, almost every concern that you might think of has
already
been (at least) thought about. In a perfect world, every concern
could be addressed perfectly. But in this world we just have to
slog
through.
1.7) What's the difference between "perl" and "Perl"?
32! [ ord('p') - ord('P') ] (Shouldn't that be 42, the Answer to
the
Great Question of Life, the Universe, and Everything? ;)
Larry now uses "Perl" to signify the language proper and "perl"
the
implementation of it, i.e. the current interpreter. Hence Tom's
quip that "Nothing but perl can parse Perl."
On the other hand, the aesthetic value of casewise parallelism in
"awk", "sed", and "perl" as much require the lower-case version as
"C",
"Pascal", and "Perl" require the upper-case version. It's also
easier
to type "Perl" in typeset print than to be constantly switching in
Courier. :-)
In other words, it doesn't matter much, especially if all you're
doing
is hearing someone talk about the language; case is hard to
distinguish
aurally.
1.8) Is it a perl program or a perl script?
It depends on whether you are talking about the perl binary or
something that you wrote using perl. And, actually, even this
isn't
necessarily true.
"Standard" UNIX terminology is (roughly) this: programs are
compiled
into machine code once and run multiple times, scripts are
translated
(by a program) each time they are used. However, some say that a
program is anything written which is executed on a computer
system.
Larry considers it a program if it is set in stone and you can't
change
it, whereas if you can go in and hack at it, it's a script. Of
course,
if you have the source code, that makes just about anything a
script. ;)
In general, it probably doesn't really matter. The terms are used
interchangeably. If you particularly like one or the other, use
it. If
you want to call yourself a perl programmer, call them programs.
If
you want to call yourself a perl scripter, call them scripts.
Randal*
and I (at least) will call them hacks. (See question 2.10 ;)
1.9) Is perl difficult to learn?
Not at all. Many people find Perl extremely easy to learn. There
are
at least three main reasons for this.
The first reason is that most of Perl has been derived from
standard
utilities, tools, and languages that you are (probably) already
familiar with. If you have any knowledge of the C programming
language
and standard C library, the Unix Shell, sed and awk, Perl should
be
simple and fun for you to learn.
The second reason that Perl is easy to learn is that you only have
to
know a very small subset of Perl to be able to get useful results.
In
fact, once you can master
#!/usr/local/bin/perl
úÿ
print "Hello, world\n";
you can start writing Perl scripts. In fact, you will probably
never
have to (or be able to) know everything about Perl. As you feel
the
need or desire to use more sophisticated features (such as C
structures
or networking), you can learn these as you go. The learning curve
for
Perl is not a steep one, especially if you have the headstart of
having
a background in UNIX. Rather, its learning curve is gentle and
gradual, but it *is* admittedly rather long.
The third reason is that you can get immediate results from your
scripts. Unlike a normal compiled language (like C or Pascal, for
example), you don't have to continually recompile your program
every
time you change one little thing. Perl allows you to experiment
and
test/debug quickly and easily. This ease of experimentation
flattens
the learning curve even more.
If you don't know C or UNIX at all, it'll be a steeper learning
curve,
but what you then learn from Perl will carry over into other
areas,
like using the C library, UNIX system calls, regular expressions,
and
associative arrays, just to name a few. To know Perl is to know
UNIX,
and vice versa.
1.10) Should I program everything in Perl?
Most definitely. In fact, you should delete the binaries for sed,
awk,
cc, gcc, grep, rm, ls, cat... well, just delete your /bin
directory.
But seriously, of course you shouldn't. As with any job, you
should
use the appropriate tool for the task at hand. Just because a
hammer
will put screws into a piece of board, you probably don't want to
do
that.
While it's true that the answer to the question "Can I do (some
arbitrary task) in Perl?" is almost always "yes", that doesn't
mean
this is necessarily a good thing to do. For many people, Perl
serves
as a great replacement for shell programming. For a few people,
it
also serves as a replacement for most of what they'd do in C. But
for
some things, Perl just isn't the optimal choice, such as tasks
requiring very complex data structures.
1.11) How does Perl compare with other scripting languages, like Tcl,
Python
or REXX?
REXX is an interpreted programming language first seen on IBM
systems.
Python is an interpreted programming language by Guido van
Rossum*.
TCL is John Ousterhout*'s embeddable command language, designed
just
for embedded command extensions, but lately used for larger
applications. TCL's most intriguing feature for many people is
the
tcl/tk toolset that allows for interpreted X-based tools. Others
use
it for its "expect" extension.
To avoid any flamage, if you really want to know the answer to
this
question, probably the best thing to do is try to write equivalent
code to do a set of tasks. All three have their own newsgroups in
which you can learn about (but hopefully not argue about) these
languages.
To find out more about these or other languages, you might also
check
out David Muir Sharnoff*'s posting "Catalog of Compilers,
Interpreters,
and Other Language Tools" which he posts to comp.lang.misc,
comp.sources.d, comp.archives.admin, and news.answers newsgroups.
It's
a comprehensive treatment of many different languages. (Caveat
lector:
he considers Perl's syntax "unappealing".)
1.12) How can I get Perl over the Internet?
Perl is available from any comp.sources.misc archive. You can use
an
archie server (see the alt.sources FAQ in news.answers) to find
these
if you want.
Volume Issues Patchlevel and Notes
------ ------ ------------------------------------------------
18 19-54 Patchlevel 3, Initial posting.
20 56-62 Patches 4-10
Since 1993, a number of archives have sprung up specifically for
Perl
and Perl related items. Larry maintains the official distribution
site (for both perl4.036 and perl5) at netlabs. Probably the
largest
archive is at the University of Florida. In order of probability
these
sites will have the sources.
Site IP Directory and notes
----------- ------- -------------------------------
North America:
ftp.netlabs.com 192.94.48.152 /pub/outgoing/perl[VERSION]/
ftp.cis.ufl.edu 128.227.100.198 /pub/perl/src/[VERSION]/
prep.ai.mit.edu 18.71.0.38 /pub/gnu/perl5.000.tar.gz
ftp.uu.net 192.48.96.9 /languages/perl/perl5.000.tar.gz
ftp.khoros.unm.edu 198.59.155.28 /pub/perl/perl5.000.tar.gz
ftp.cbi.tamucc.edu 165.95.1.3
/pub/duff/Perl/perl5.000.tar.gz
ftp.metronet.com 192.245.137.1 /pub/perl/sources/
genetics.upenn.edu 128.91.200.37 /perl5/perl5_000.zip
Europe:
ftp.cs.ruu.nl 131.211.80.17
/pub/PERL/perl5.0/perl5.000.tar.gz
ftp.funet.fi 128.214.248.6
/pub/languages/perl/ports/perl5/perl5.000.tar.gz
ftp.zrz.tu-berlin.de 130.149.4.40
/pub/unix/perl/perl5.000.tar.gz
src.doc.ic.ac.uk 146.169.17.5
/packages/perl5/perl5.000.tar.gz
Australia:
sungear.mame.mu.oz.au 128.250.209.2
/pub/perl/src/5.0/perl5.000.tar.gz
If there is a site in Asia or Japan, please tell us about it.
Thanks!
You can also retrieve perl via non-ftp methods:
http: //src.doc.ic.ac.uk/packages/perl5/perl5.000.tar.gz
gopher:
//src.doc.ic.ac.uk/0/packages/perl5/perl5.000.tar.gz
1.13) How can I get Perl via Email?
The following is a list of known ftpmail sites. Please attempt to
use
the site closest to you with the ftp archive closest to it. Many
of
these sites already have perl on them. For information on how to
use
one of these sites, send email containing the word "help" to the
address.
United States:
Massachusetts: ftpmail@decwrl.dec.com
New Jersey: bitftp@pucc.princeton.edu
North Carolina: ftpmail@sunsite.unc.edu
Europe/UK:
Germany: ftpmail@ftp.uni-stuttgart.de
bitftp@vx.gmd.de
UK: ftpmail@doc.ic.ac.uk
Australia: ftpmail@cs.uow.edu.au
Henk P Penning* suggests that if you are in Europe you should try
the
following (if you are in Germany or the UK, you should probably
use one
of the servers listed above):
Email: Send a message to 'mail-server@cs.ruu.nl' containing:
begin
path your_email_address
send help
send PERL/INDEX
end
The path-line may be omitted if your message contains a normal
From:-line. You will receive a help-file and an index of the
directory that contains the Perl stuff.
If all else fails, mail to Larry usually suffices.
1.14) How can I get Perl via UUCP?
There currently is no way of getting Perl via UUCP. If anyone
knows of
a way, please contact me. The OSU site has discontinued the
service.
1.15) Are there other ways of getting perl?
Another possibility is to use UUNET, although they charge you for
it.
You have been duly warned. Here's the advertisement:
Anonymous Access to UUNET's Source Archives
1-900-GOT-SRCS
UUNET now provides access to its extensive collection of UNIX
related sources to non- subscribers. By calling 1-900-468-7727
and using the login "uucp" with no password, anyone may uucp any
of UUNET's on line source collection. Callers will be charged 40
cents per minute. The charges will appear on their next tele-
phone bill.
The file uunet!/info/help contains instructions. The file
uunet!/index//ls-lR.Z contains a complete list of the files
available and is updated daily. Files ending in Z need to be
uncompressed before being used. The file uunet!~/compress.tar is
a tar archive containing the C sources for the uncompress program.
This service provides a cost effective way of obtaining
current releases of sources without having to maintain accounts
with UUNET or some other service. All modems connected to the
900 number are Telebit T2500 modems. These modems support all
standard modem speeds including PEP, V.32 (9600), V.22bis (2400),
Bell 212a (1200), and Bell 103 (300). Using PEP or V.32, a 1.5
megabyte file such as the GNU C compiler would cost $10 in con-
nect charges. The entire 55 megabyte X Window system V11 R4
would cost only $370 in connect time. These costs are less than
the official tape distribution fees and they are available now
via modem.
UUNET Communications Services
3110 Fairview Park Drive, Suite 570
Falls Church, VA 22042
+1 703 876 5050 (voice)
+1 703 876 5059 (fax)
info@uunet.uu.net
1.16) Has perl been ported to machine FOO?
Perl runs on virtually all Unix machines simply by following the
hints
file and instructions in the Configure script. This auto-
configuration
script allows Perl to compile on a wide variety of platforms by
modifying the machine specific parts of the code. For most Unix
systems, or VMS systems for v5 perl, no porting is required. Try
to
compile Perl on your machine. If you have problems, examine the
README
file carefully. If all else fails, send a message to
comp.lang.perl
and crosspost to comp.sys.[whatever], there's probably someone out
there that has already solved your problem and will be able to
help you
out.
Perl has been ported to many non-Unix systems, although currently
there
are no v5 ports. All of the following are mirrored at
ftp.cis.ufl.edu:/pub/perl/src/[OS]/. The following are the
(known)
official distribution points. Please contact the porters directly
(when possible) in case of questions on these ports.
* MS-DOS binaries and source are available at ftp.ee.umanitoba.ca
[130.179.8.47] in /pub/msdos/perl
There are currently half a dozen different ports for MS-DOS.
BigPerl4 (v3) is perl4.036 compiled with the Watcom C/386
compiler (32-bit, flat-memory model C compiler) with the
following features:
* Up to 32MB of memory can be used.
* Supports virtual memory.
* Works under Windows 3.1 (however, a second copy of perl cannot
be spawned under Windows).
* The perl debugger can be used.
* Contains GDBM support.
* Windows/NT binaries are available from ftp.cis.ufl.edu. Does
anyone know the official distribution point? I got these from
archive.cis.ohio-state.edu quite awhile back.
* Machintosh binaries and source are available from nic.switch.ch
[130.59.1.40] in /software/mac/perl.
Version 4.1.3 is perl4.036 compiled with the MPW C compiler
* Mac_Perl_413_src.sit.bin Sources
* Mac_Perl_413_tool.sit.bin MPW Tool
* Mac_Perl_413_appl.sit.bin Standalone Application
There is a mailing list for discussing Macintosh Perl. Contact
"mpw-perl-request@iis.ee.ethz.ch".
Timothy Murphy* also ported a version of perl to the Macintosh
using Think C. It has probably been abandoned in favour of the
MPW port, but is still available at ftp.maths.tcd.ie
[134.266.81.10] in the directory /pub/Mac/perl-4.035/.
* OS/2 sources are also available at ftp.cis.ufl.edu in
/pub/perl/src/os2. This appears to have been abandoned and added
to the official distribution. See the directory os2 in the perl5
sources.
* VMS systems should be able to build directly from the standard
distribution.
1.17) How do I get Perl to compile on Solaris?
The following directions are for perl, version 4. Perl, version
5,
should compile more easily. If not, send mail to The Perl Porters
Mailing List (perl5-porters@isu.edu)
John Lees* reports:
I have built perl on Solaris 2.1, 2.2 beta, and 2.2 FCS. Take
/usr/ucb out of your path and do not use any BSD/UCB libraries.
Only -lsocket, -lnsl, and -lm are needed. You can use the hint for
Solaris 2.0, but the one for 2.1 is wrong. Do not use vfork. Do not
use -I/usr/ucbinclude. The result works fine for me, but of couse
does not support a couple of BSDism's.
Casper H.S. Dik* reports
You must remove all the references to /usr/ucblib AND
/usr/ucbinclude. And ignore the Solaris_2.1 hints. They are
wrong.
The undefining of vfork() probably has to do with the
confusion it
gives to the compilers. If you use cc, you mustn't compile
util.c/tutil.c with -O. I only used the following libs: -lsocket
-lnsl -lm (there is a problem with -lmalloc)
Michael D'Errico* reports:
If you are using Solaris 2.x, the signal handling is broken.
If
you set up a signal handler such as 'ripper' it will be forgotten
after the first time the signal is caught. To fix this, you need
to recompile Perl. Just add '#define signal(x,y) sigset((x),(y))'
after the '#include <signal.h>' directive in each file that it
occurs, then make it again.
1.18) How do I get Perl to compile on a Next?
According to Andreas Koenig*, under NeXTstep 3.2, both perl4.036
and
perl5.000 compile with the supplied hints file.
However, Bill Eldridge* provides this message to help get
perl4.036 on
NeXTstep 3.0 to work:
To get perl to compile on NeXTs, you need to combine the ANSI
and BSD headers:
cd /usr/include
mkdir ansibsd
cd ansibsd
ln -s ../ansi
ln -s ../bsd
Then, follow the configuration instructions for NeXTs,
*replacing*
all mention of -I/usr/include/ansi or -I/usr/include/bsd with
-I/usr/include/ansibsd.
1.19) What extensions are available from Perl and where can I get
them?
Some of the more popular extensions include those for windowing,
graphics, or data base work. See perlmod(1).
Tk (as in tcl/tk, but sans tcl)
ftp://ftp.cis.ufl.edu/pub/perl/src/tkperl/tkperl5a5.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/tkperl5a5.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/tkperl/tkperl5a5.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/tkperl5a5.tar.gz
ftp://black.ox.ac.uk/src/ALPHA/tkperl5a5.tar.gz
Curses (standard C library)
ftp://ftp.ncsu.edu/pub/math/wsetzer/cursperl5a6.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/cursperl5a6.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/cursperl5a6.tar.gz
Msql (SQL)
ftp://ftp.zrz.TU-Berlin.DE/pub/unix/perl/MsqlPerl-a1.tgz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/MsqlPerl-a1.tgz
ftp://ftp.metronet.com/pub/perlinfo/perl5/MsqlPerl5-a1.tgz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/MsqlPerl-a1.tar.gz
Sx (Athena & Xlib)
ftp://ftp.pasteur.fr/pub/Perl/Sx.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/Sx.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/Sx.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/PerlDoc.ps.gz
1.20) What is dbperl and where can I get it?
Many database-oriented extensions to Perl have been written.
Basically, these use the usub mechanism (see the usub/
subdirectory) in
the source distribution) to link in a database library, allowing
embedded calls to Informix, Ingres, Interbase, Oracle and Sybase.
Here are the authors of the various extensions:
What Target DB Who
-------- ----------- -----------------------------------
-----
?Infoperl Informix Kurt Andersen
(kurt@hpsdid.sdd.hp.com)
Ingperl Ingres Tim Bunce (timbo@ig.co.uk) and Ted Lemon
Interperl Interbase Buzz Moschetti (buzz@bear.com)
Isqlperl Informix William Hails, bill@tardis.co.uk
Oraperl Oracle Kevin Stock (kstock@Auspex.com)
Pgperl Postgres Igor Metz (metz@iam.unibe.ch)
*Sqlperl Ingres Ted Lemon (mellon@ncd.com)
Sybperl Sybase Michael Peppler (mpeppler@itf.ch)
Uniperl Unify 5.0 Rick Wargo (rickers@coe.drexel.edu)
? Does this one still exist?
* Sqlperl appears to have been subsumed by Ingperl
Buzz Moschetti* has organized a project to create a higher level
interface to will allow you to write your queries in a database-
independent fashion. If this type of project interests you, send
to <perldb-interest-request@vix.com> and asked to be placed on the
"perldb-interest" mailing lists.
Here's a bit of advertising from Buzz:
Perl is an interpreted language with powerful string, scalar, and
array processing features developed by Larry Wall that "nicely
bridges the functionality gap between sh(1) and C." Since
relational DB operations are typically textually oriented, perl is
particularly well-suited to manage the data flows. The C source
code, which is available free of charge and runs on many platforms,
contains a user-defined function entry point that permits a
developer to extend the basic function set of the language. The
DBperl Group seeks to exploit this capability by creating a
standardized set of perl function extensions (e.g. db_fetch(),
db_attach()) based the SQL model for manipulating a relational DB,
thus providing a portable perl interface to a variety of popular
RDMS engines including Sybase, Oracle, Ingres, Informix, and
Interbase. In theory, any DB engine that implements a dynamic SQL
interpreter in its HLI can be bolted onto the perl front end with
predicatable results, although at this time backends exist only for
the aforementioned five DB engines.
The official archive for DBperl extensions is ftp.demon.co.uk:
/pub/perl/db. It's the home of the evolving DBperl API
Specification.
Here's an extract from the updated README there:
DBI/ The home of the DBI archive. To join the DBI mailing list
send your request to perldb-interest-REQUEST@vix.com
úÿ
DBD/ Database Drivers for the DBI ...
Oracle/ By Tim Bunce (not yet ready!)
Ingres/ By Tim Bunce (not yet started!)
mod/ Other Perl 5 Modules and Extensions ...
Sybperl/ By Michael Peppler, mpeppler@itf.ch
perl4/ Perl 4 extensions (using the usub C interface)
oraperl/ ORACLE 6 & 7 By Kevin Stock (sadly no longer on the
net)
sybperl/ SYBASE 4 By Michael Peppler, mpeppler@itf.ch
ingperl/ INGRES By Tim Bunce timbo@ig.co.uk and Ted
Lemon
isqlperl/ INFORMIX By William Hails, bill@tardis.co.uk
interperl/ INTERBASE By Buzz Moschetti, buzz@bear.com
oraperl/ ORACLE 6 & 7 By Kevin Stock (sadly no longer on the
net)
sybperl/ SYBASE 4 By Michael Peppler, mpeppler@itf.ch
ingperl/ INGRES By Tim Bunce timbo@ig.co.uk and Ted
Lemon
isqlperl/ INFORMIX By William Hails, bill@tardis.co.uk
interperl/ INTERBASE By Buzz Moschetti, buzz@bear.com
uniperl/ UNIFY 5.0 By Rick Wargo, rickers@coe.drexel.edu
pgperl/ POSTGRES By Igor Metz, metz@iam.unibe.ch
btreeperl/ NDBM perl extensions. By John Conover,
john@johncon.com
ctreeperl/ C-Tree perl extensions. By John Conover,
john@johncon.com
duaperl/ X.500 Directory User Agent. By Eric Douglas.
scripts/ Perl and shell scripts
rdb/ RDB is a perl RDBMS for ASCII files. By Walt Hobbs,
hobbs@rand.org
shql/ SHQL is an interactive SQL database engine. Written
as a
shell script, SHQL interprets SQL commands and
manipulates flat files based on those commands. By
Bruce Momjian, root@candle.uucp
xbase/ Perl scripts for accessing xBase style files (dBase
III)
refinfo/ Reference information
sqlsyntax/ Yacc and lex syntax and C source code for SQL1 and
SQL2
from
ftp.uu.net:/pub/uunet/published/oreilly/nutshell/yacclex,
and a draft SQL3 syntax from Jeff Fried
<jfried@informix.com>+
formats/ Details of file formats such as Lotus 1-2-3 .WK1
There are also a number of non SQL database interfaces for perl
available from ftp.demon.co.uk. These include:
Directory Target System Authors and notes
--------- ------------- -------------------------------------------
btreeperl NDBM extension John Conover (john@johncon.com)
ctreeperl CTree extension John Conover (john@johncon.com)
duaperl X.500 DUA Eric Douglas
rdb RDBMS Walt Hobbs (hobbs@rand.org)
shql SQL Engine Bruce Momjian (root@candle.uucp)
1.21) Which DBM should I use?
As shipped, Perl (version 5) comes with interfaces for several DBM
packages (SDBM, old DBM, NDBM, GDBM, Berkeley DBM) that are not
supplied
but either come with your system are readily accessible via FTP.
SDBM
is guaranteed to be there. For a comparison, see AnyDBM_File(3pm)
and DB_File(3pm).
1.22) Is there an SNMP aware Perl?
snmperl was written by Guy Streeter (streeter@ingr.com), and was
posted in late February 1993 to comp.protocols.snmp. It can be
found
archived at one of two (known) places:
Host liasun3.epfl.ch
Location: /pub/net/snmp
FILE -rw-rw-r-- 3407 Aug 11 1992 snmperl.README
FILE -rw-r--r-- 17678 Aug 11 1992 snmperl.tar.Z
Host ftp.cis.ufl.edu
Location: /pub/perl/scripts/snmp
Here is the gist of the README:
README $Revision: 2.3 $
This directory contains the source code to add callable C
subroutines
to perl. The subroutines implement the SNMP functions "get",
"getnext", and "set". They use the freely-distributable SNMP
package
(version 1.1b) from CMU.
USE:
There are four subroutines defined in the callable interface:
snmp_get, snmp_next, snmp_set, and snmp_error.
snmp_get and snmp_next implement the GET and GETNEXT operations,
respectively. The first two calling arguments are the hostname
and
Community string. The IP address of the host, as a dotted-quad
ASCII
string, may be used as the hostname. The rest of the calling
arguments are a list of variables. See the CMU package
documentation
for how variables may be specified.
snmp_set also takes hostname and Community string as arguments.
The
remaining arguments are a list of triples consisting of variable
name,
variable type, and value. The variable type is a string, such as
"INTEGER" or "IpAddress".
snmp_get, snmp_next, and snmp_set return a list containing
alternating variables and values. snmp_get and snmp_next will
simply
omit non-existent variables on return. snmp_set will fail
completely
if one of the specified variables does not exist (or is read-
only).
snmp_error will return a text string containing some error
information about the most recent snmp_get|next|set call, if it
had an
error.
OTHER NOTES:
I didn't find all the places where the CMU library writes to
stderr
or calls exit() directly.
The changes I made to mib.c involve the formatting of variable
values
for return to the caller. I took out the descriptive prefix so
the
string contains only the value.
Enumerated types are returned as a string containing the
symbolic
representation followed in parentheses by the numeric.
DISTRIBUTION and OWNERSHIP
perl and the CMU SNMP package have their own statements. Read
them.
The work I've done is free and clear. Just don't say you wrote it
if
you didn't, and don't say I wrote it if you change it.
Guy Streeter
streeter@ingr.com
April 1, 1992 (not a joke!)
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 2/5 - Information Sources
Message-ID: <perl-faq/part2_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
swrinde!hookup!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 2/5 - Information Sources
Supersedes: <perl-faq/part2_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:58 GMT
Organization: none
Lines: 579
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part2_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39242 comp.answers:8359
news.answers:32286
Archive-name: perl-faq/part2
Version: $Id: part2,v 2.3 1994/11/07 18:05:30 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to general information questions, mostly
of
about information sources.
2.1) Is there a USENET group for Perl?
Yes there is: comp.lang.perl. This group, which currently can get
up
to 100 messages per day, contains all kinds of discussions about
Perl;
everything from bug reports to new features to the history to
humour
and trivia. This is the best source of information about anything
Perl
related, especially what's new with Perl5. Because of it's vast
array
of topics, it functions as both a comp.lang.* style newsgroup
(providing technical information) and also as a rec.* style
newsgroup,
kind of a support group for Perl addicts (PerlAnon?).
Larry is a frequent poster to this group as well as most (all?) of
the
seasoned Perl programmers. Questions will be answered by some of
the
most knowledgable Perl Hackers, often within minutes of a question
being posted (give or take distribution times).
2.2) Have any books or magazine articles been published about Perl?
There have been quite a few books and articles. The most well
known
and most useful book for 4.036 and earlier is _Programming Perl_
(affectionately known as ``the Camel Book''), written by Larry and
Randal Schwartz*, published by O'Reilly & Associates as part of
their
Nutshell Handbook Series (ISBN: 0-937175-64-1). Besides serving
as a
reference guide for Perl, it also contains tutorial material and
is a
great source of examples and cookbook procedures, as well as wit
and
wisdom, tricks and traps, pranks and pitfalls. The code examples
contained therein are available via anonymous FTP from ftp.ora.com
in
/pub/examples/nutshell/programming_perl/perl.tar.Z or at
ftp.cis.ufl.edu in /pub/perl/ora/programming_perl. Corrections
and
additions to the book can be found in the Perl man page right
before
the BUGS section under the heading ERRATA AND ADDENDA.
A new version of the Camel book, revised and updated for Perl5 is
due
out sometime around spring of next year. Until then, the man
pages
distributed with the perl 5.000 source contain a wealth of
information
on the new features and old incompatibilities with perl4.036.
Also available is ``the Llama Book'', _Learning Perl_ by Randal
Schwartz, another Nutshell book. This book is a collection of
some of
the best introductory and tutorial information available about
Perl. A
definite must for novice Perl users. The examples and code from
this
book are available from the same places as the Camel book code.
(ISBN:
1-56592-042-2)
If you can't find these books in your local technical bookstore,
they
may be ordered directly from O'Reilly by calling 1-800-998-9938 if
in
North America and 1-707-829-0515 otherwise.
Larry routinely carries around a camel stamp to use when
autographing
copies of his book. If you can catch him at a conference you can
usually get him to sign your book for you.
Larry Wall has published a 3-part article on perl in Unix World
(August through October of 1991), and Rob Kolstad also had a 3-
parter
in Unix Review (May through July of 1990). Tom Christiansen also
has
a brief overview article in the trade newsletter Unix Technology
Advisor from November of 1989. You might also investigate "The
Wisdom
of Perl" by Gordon Galligher from SunExpert magazine; April 1991
Volume 2 Number 4. The Dec 92 Computer Language magazine also
contains a cover article on Perl, "Perl: the Programmers Toolbox".
Many other articles on Perl have been recently published. If you
have references, especially on-line copies, please mail them to
the FAQ maintainer for inclusion is this notice.
The USENIX LISA (Large Installations Systems Administration)
Conference
have for several years now included many papers of tools written
in
Perl. Old proceedings of these conferences are available; look in
your current issue of ";login:" or send mail to office@usenix.org
for further information.
At this point, the "writing committe" (Larry, Randal, and Tom; aka
<perlbook@perl.com>) is looking at:
o A heavy rewrite of the Camel to update it to Perl5. Expect the
tutorial section to be cut in deference to the Llama.
o A light update of the Llama to eliminate the "I think perl5 will
do ..." and a change to "Perl5 will do ..."
o A new book, "Learning More Perl" (working title), a sequel to the
Llama, covering what wasn't covered in the Llama including Perl5.
According to Randal, this is the current priority. However, he
notes
that the new Camel won't be out until sometime in the spring of
next
year, at the earliest.
Prentice Hall also has two perl books, either on the shelves or in
the
works. The first is ``Perl by Example'' by Ellie Quigley. (385
pages,
$26.96, ISBN 0-13-122839-0) A perl tutorial (perl4); every feature
is
presented via an annotated example and sample output.
The second book is called ``Software Engineering with Perl'' by
Carl
Dichter and Mark Pease. Randal Schwartz has reviewed the second
book
(SEwP) and has this to say about it:
SWwP is not meant as instruction in the Perl language, but rather
as an example of how Perl may be used to assist in the semi-formal
software engineering development cycles. There's a lot of Perl
code that's fairly well commented, but most of the book describes
software engineering methodologies. For the perl-challenged,
there's a *light* treatment of the language as well, but they refer
to the llama and the camel for the real meat.
Japan seems to be jumping with Perl books. If you can read
japanese
here are a few you might be interested in. Thanks to Jeffrey
Friedl*
for this list (NOTE: my screen cannot handle japanese characters,
so
this is all in English for the moment NOTE2: These books are
written
in Japanese, these titles are just translations):
Title: Welcome to Perl Country
Authors: Kaoru Maeda, Hiroshi Koyama, Yasushi Saito and Arihito
Fuse
Publisher: Science Company Date: April 25, 1993
ISBN: 4-7819-0697-4 Price: 2472Y
Comments: Written during the time the Camel book was being
translated. A useful introduction, but uses jperl (Japanese Perl)
which is not necessarily compatible.
Title: Perl Writing Methods (Perl Calligraphy?)
Author: Toshiyuki Masui
Publisher: ASCII Corporation Date: July 1, 1993
ISBN: 4-7561-0281-6 Price: 3200Y
Comments: More advanced than "Welcome.." and not meant as an
introduction. Uses the standard perl and has examples for handling
Japanese text.
Title: Introduction to Perl
Author: Shinji Kono
Publisher: ASCII Corporation Date: July 11, 1994
ISBN: 4-7561-0292-1 Price: 1800Y
Comments: Uses the interactive Perl debugger to explain how things
work.
Title: Programming Perl
Authors: L Wall & R Schwartz Translator: Yoshiyuri Kondo
Publisher: Softbank Corporation Date: February 28, 1993
ISBN: 4-89052-384-7 Price: 4500Y
Comments: Official Japanese translation. Somewhat laced with
translator notes to explain the humour. The most useful book.
There is also a German translation of Programming Perl. It is
available
from Hanser Verlag:
Title: Programmieren in Perl
ISBN: 3-446-17257-2
2.3) When will the Camel and Llama books be updated?
When they do. :-) Actually, we're looking at having them in print
about 6 months from now (for floating values of now :-). Send the
writing committee mail (perlbook@perl.com) mail if you have
suggestions.
2.4) What FTP resources are available?
Within the past year, several ftp sites have sprung up for Perl
and
Perl related items. The site with the biggest repository of Perl
scripts right now seems to be ftp.cis.ufl.edu [128.227.100.198].
The
scripts directory has an INDEX with over 400 lines in it, each
describing what the script does. The src directory has sources
and/or
binaries for a number of different perl ports, including MS-Dos,
Macintosh and Windows/NT. This is maintained by me, Steve*.
Note: I've changed jobs recently and am not currently directly
on the Internet. This means this site may get a little out of
date until I can get back up to UF and update it. However, I
did set up automatic mirrors to many sites, so much of it should
remain uptodate. (If only Larry would put the beta patches on
netlabs....)
Note: European users please use the site src.doc.ic.ac.uk
[149.169.2.1] in /pub/computing/programming/languages/perl/
The link speed would be a lot better for all. Contact
L.McLoughlin@doc.ic.ac.uk for more information. It is updated
daily.
This may not be working yet. I'm working with Lee to get it
setup.
There are also a number of other sites. I'll add more of them as
I get
information on them.
2.5) What WWW/gopher resources are available?
The World Wide Web is exploding with new Perl sites all the time.
Some
of the more notable ones are:
http://www.cis.ufl.edu/perl
http://www.metronet.com/1h/perlinfo, which has a great section on
Perl5.
http://www.eecs.nwu.edu/perl/perl.html
http://web.nexor.co.uk/perl/perl.html, a great site for
European
and UK users.
2.6) Can people who don't have access to USENET get comp.lang.perl?
"Perl-Users" is the mailing list version of the comp.lang.perl
newsgroup. If you're not lucky enough to be on USENET you can
post to
comp.lang.perl by sending to one of the following addresses.
Which one
will work best for you depends on which nets your site is hooked
into.
Ask your local network guru if you're not certain.
Internet: PERL-USERS@VIRGINIA.EDU
Perl-Users@UVAARPA.VIRGINIA.EDU
BitNet: Perl@Virginia
uucp: ...!uunet!virginia!perl-users
The Perl-Users list is bidirectionally gatewayed with the USENET
newsgroup comp.lang.perl. This means that VIRGINIA functions as a
reflector. All traffic coming in from the non-USENET side is
immediately posted to the newsgroup. Postings from the USENET
side are
periodically digested and mailed out to the Perl-Users mailing
list. A
digest is created and distributed at least once per day, more
often if
traffic warrants.
All requests to be added to or deleted from this list, problems,
questions, etc., should be sent to:
Internet: Perl-Users-Request@Virginia.EDU
Perl-Users-Request@uvaarpa.Virginia.EDU
BitNet: Perl-Req@Virginia
uucp: ...!uunet!virginia!perl-users-request
Coordinator: Marc Rouleau <mer6g@VIRGINIA.EDU>
2.7) Are archives of comp.lang.perl available?
Yes, there are. ftp.cis.ufl.edu:/pub/perl/comp.lang.perl/monthly
has
an almost complete collection dating back to 12/89 (missing 08/91
through 12/93). They are kept as one large file for each month.
A more sophisticated query and retrieval mechanism is desirable.
Preferably one that allows you to retrieve article using a fast-
access
indices, keyed on at least author, date, subject, thread (as in
"trn")
and probably keywords. Right now, the MH pick command works for
this,
but it is very slow to select on 18000 articles.
If you have, or know where I can find, the missing sections,
please let
perlfaq@perl.com know.
2.8) Is there a WAIS server for comp.lang.perl?
Yes there is. Set your WAIS client to
archive.orst.edu:9000/comp.lang.perl. According to their
introduction,
they have a complete selection from 1989 on.
Bill Middleton <wjm@feenix.metronet.com> offers this:
"I have setup a perl script retrieval service and WaisSearch here
at
feenix. To check it out, just point your gopher at us, and select
the
appropriate menu option. The WaisSearch is of the iubio type,
which
means you can do boolean searching. Thus you might try something
like:
caller
ioctl and fcntl
grep and socket not curses
and other things to see examples of how other folks have done this
or that. This service is still under construction, but I'd like
to
get feedback, if you have some time.
There's also a WaisSearch into all the RFC's and some other fairly
nifty stuff."
2.9) What other sources of information about Perl or training are
available?
Johan Vromans* created an beautiful reference guide. The
reference
guide comes with the Camel book in a nice, glossy format. The
LaTeX
(source) and PostScript (ready to print) versions are available
for FTP
from ftp.cs.ruu.nl:/pub/DOC/perlref-4.036.1.tar.Z in Europe or
from
ftp.cis.ufl.edu:/pub/perl/doc/perlref-4.036.tar.gz in the United
States. Obsolete versions in TeX or troff may still be available,
but
these versions don't print as nicely. See also:
[] ftp://ftp.uu.net/languages/perl/perlref-4.036.1.tar.gz
[] ftp://ftp.cs.ruu.nl/pub/DOC/perlref-4.036.1.tar.gz
[] ftp://ftp.khoros.unm.edu/pub/perl/perlref-4.036.1.tar.gz
Johan is working on an update to this document to include perl5
functionality, which he hopes to release by Christmas 1994.
There is a #Perl channel on IRC (Internet Relay Chat) where Tom
and
Randal have been known to hang out. Here you can get immediate
answers
to questions from some of the most well-known Perl Hackers.
The perl5-porters (perl5-porters@isu.edu) mailing list was created
to
aid in communication among the people working on perl5. However,
it
has overgrown this function and now also handles a good deal of
traffic
about perl internals.
2.10) Where can I get training classes on Perl?
USENIX, LISA, SUG, WCSAS, AUUG, FedUnix and Europen sponsor
tutorials
of varying lengths on Perl at the System Administration and
General
Conferences. These public classes are typically taught by Tom
Christiansen*.
In part, Tom and Randal teach Perl to help keep bread on their
tables
long enough while they continue their pro bono efforts of
documenting
perl (Tom keeps writing more man pages for it :-) and expanding
the
perl toolkit through extension libraries, work which they enjoy
doing
as it's fun and helps out the whole world, but which really
doesn't
pay the bills. Such is the nature of free(ly available) software.
Send mail to <perlclasses@perl.com> for details and availability.
Tom is also available to teach on-site classes, included courses
on
advanced perl and perl5. Classes run anywhere from one day to
week
long sessions and cover a wide range of subject matter. Classes
can
include lab time with exercises, a generally beneficial aspect.
If you
would like more information regarding Perl classes or when the
next
public appearances are, please contact Tom directly.
Randal Schwartz* provides a 2-day lecture-only and a 4-5 day
lecture-lab
course based on his popular book "Learning Perl". For details,
contact
Randal directly via email or at 1.503.777.0095.
Internet One provides a 2 day "Introduction to Perl" and 2 day
"Advanced Perl" workshop. The 50% hands-on and 50% lecture format
allow attendees to write several programs themselves. Supplied
are the user manuals, reference copies of Larry Wall's "Program-
ming Perl", and a UNIX directory of all training examples and
labs. To obtain outlines, pricing, or scheduling information, use
the following:
o Phone: 1.303.444.1993
o Email: info@InternetOne.COM
o See our Ad in the "SysAdmin" magazine
o View the outlines via the Web: http://www.InternetOne.COM/
2.11) What companies use or ship Perl?
At this time, the known list of companies that ship Perl includes
at
least the following, although some have snuck it into /usr/contrib
or
its moral equivalent:
BSDI
Comdisco Systems
CONVEX Computer Corporation
Crosspoint Solutions
Dell
DRD Corporation
IBM (SP systems)
Intergraph
Kubota Pacific
Netlabs
SGI (without taintperl)
Univel
Furthermore, the following vendors are reported to begin shipping
perl
standard with their systems in the very near future:
Sun
Some companies ship it on their "User Contributed Software Tape",
such as DEC and HP. Apple Computer has shipped the MPW version of
Macintosh Perl on one of their Developer CDs
(Essentials*Tools*Objects
#11) (and they included it under "Essentials" :-)
Many other companies use Perl internally for purposes of tools
development, systems administration, installation scripts, and
test
suites. Rumor has it that the large workstation vendors (the TLA
set)
are seriously looking into shipping Perl with their standard
systems
"soon".
úÿ
People with support contracts with their vendors are actively
encouraged to submit enhancement requests that Perl be shipped
as part of their standard system. It would, at the very least,
reduce the FTP load on the Internet. :-)
If you know of any others, please send them in.
2.12) Is there commercial, third-party support for Perl?
Not really. Although perl is included in the GNU distribution, at
last
check, Cygnus does not offer support for it. However, it's
unclear
whether they've ever been offered sufficient financial incentive
to do
so.
On the other hand, you do have comp.lang.perl as a totally gratis
support mechanism. As long as you ask "interesting" questions,
you'll
probably get plenty of help. :-)
While some vendors do ship Perl with their platforms, that doesn't
mean
they support it on arbitrary other platforms. And in fact, all
they'll
probably do is forward any bug reports on to Larry. In practice,
this
is far better support than you could hope for from nearly any
vendor.
The companies who won't use something unless they can pay money
for it
will be left out. Often they're motivated by wanting someone whom
they
could sue. If all they want is someone to help them out with Perl
problems, there's always the net. And if they really want to pay
someone for that help, well, Tom and Randal are always looking for
a
job. :-)
If companies want "commercial support" for it badly enough, speak
up --
something might be able to be arranged.
2.13) What is a JAPH? What does "Will hack perl for ..." mean?
These are the "just another perl hacker" signatures that some
people
sign their postings with. About 100 of the of the earlier ones
are
available from the various FTP sites.
When people started running out of tricky and interesting JAPHs,
some
of them turned to writing "Will hack perl for ..." quotes. While
sometimes humourous, they just didn't have the flair of the JAPHs
and
have since almost completely vanished.
2.14) Where can I get a list of Larry Wall witticisms?
Over a hundred quips by Larry, from postings of his or source
code,
can be found in many of the FTP sites or through the World Wide
Web at
"ftp://ftp.cis.ufl.edu/pub/perl/misc/lwall-quotes"
2.15) What are the known bugs?
These apply to version 5 of perl. See also: `What does "Malformed
command links" mean?' for a version 4 bug.
The README says it's a pre-release.
Workaround: ignore this sentence.
Installs perl0.000 and sperl0.000 instead of 5.000.
Workaround: rename the files.
The debugger appears to be broken on "my" variables;
Workaround: none yet
Recursive signal handlers eventually core dump.
Workaround: ease up on the ^C key.
The following code misbehaves: print ++$_ . "\n" until /0/;
Workaround: initialize your variable
Destructors can clobber $@ on exit from an eval
Workaround: local $@; eval {...};
2.16) Where should I post bugs?
The best place to send your bug is <perlbug@perl.com>, which is
currently just alias for <perl5-porters@isu.edu>. You may
subscribe
to the list in the customary fashion via mail to
<perl5-porters-request@isu.edu>. Feel free to post your bugs to
the
comp.lang.perl newsgroup as well, but do make sure they still go
to
the mailing list.
To enhance your chances of getting any bug you report fixed:
1. Try to narrow the problem down to as small a piece of code as
possible. If you can get it down to 1 line of Perl then so
much
the better.
2. Include a copy of the output from the myconfig script from the
Perl source distribution in your posting.
2.17) Where should I post source code?
You should post source code to whichever group is most
appropriate,
but feel free to cross-post to comp.lang.perl. If you want to
cross-post to alt.sources, please make sure it follows their
posting standards, including setting the Followups-To header
line to NOT include alt.sources; see their FAQ for details.
2.18) Where can I learn about object-oriented Perl programming?
The perlobj(1) man page is a good place to start, and then you can
check out the excellent perlbot(1) man page written by the dean of
perl
o-o himself, Dean Roehrich. Areas covered include the following:
Idx Subsections in perlobj.1 Lines
1 NAME 2
2 DESCRIPTION 16
3 An Object is Simply a Reference 60
4 A Class is Simply a Package 31
5 A Method is Simply a Subroutine 34
6 Method Invocation 75
7 Destructors 14
8 Summary 7
Idx Subsections in perlbot.1 Lines
1 NAME 2
2 INTRODUCTION 9
3 Instance Variables 43
4 Scalar Instance Variables 21
5 Instance Variable Inheritance 35
6 Object Relationships 33
7 Overriding Superclass Methods 49
8 Using Relationship with Sdbm 45
9 Thinking of Code Reuse 111
The section on instance variables should prove very helpful to
those
wondering how to get data inheritance in perl.
2.19) Where can I learn about linking C with Perl? [h2xs]
While it used to be deep magic, how to do this is now revealed in
the
perlapi(1), perlguts(1), and perlcall(1) man pages, which treat
with
this matter extensively.
2.20) What is perl.com?
Perl.com is just Tom's domain name, registered as dedicated to
"Perl
training and consulting". While not a proper ftp site (he hasn't
got
the bandwidth (yet)), it does serve as a clearinghouse for certain
perl related mailing list. That means that you should always be
able
to get to Larry, Tom, or Randal through that host. The following
aliases work:
perl-packrats: The archivist list
perl-porters: The porters list
perlbook: The Camel/Llama/Alpaca writing committee
perlbugs: The bug list (perl-porters for now)
perlclasses: Info on Perl training
perlfaq: Submissions/Errata to the Perl FAQ
(Tom and Steve)
perlrefguide: Submissions/Errata to the Perl FAQ
(Johan)
y
2.21) What do the asterisks (*) throughout the FAQ stand for?
To keep from cluttering up the FAQ and for easy reference all
addresses have been collected in this location. For each person
listed, I offer my thanks for their input and help.
* Larry Wall <lwall@netlabs.com>
* Tom Christiansen <tchrist@wraeththu.cs.colorado.edu>
* Stephen P Potter <spp@vx.com>
* Andreas Koenig <k@franz.ww.TU-Berlin.DE>
* Bill Eldridge <bill@cognet.ucla.edu>
* Buzz Moschetti <buzz@toxicavenger.bear.com>
* Casper H.S. Dik <casper@fwi.uva.nl>
* David Muir Sharnoff <muir@tfs.com>
* Dean Roehrich <roehrich@ironwood.cray.com>
* Dominic Giampaolo <dbg@sgi.com>,
* Frederic Chauveau <fmc@pasteur.fr>
* Gene Spafford <spaf@cs.purdue.edu>
* Guido van Rossum <guido@cwi.nl>
* Henk P Penning <henkp@cs.ruu.nl>
* Jeff Friedl <jfriedl@omron.co.jp>
* Johan Vromans <jv@NL.net>
* John Dallman <jgd@cix.compulink.co.uk>
* John Lees <lees@pixel.cps.msu.edu>
* John Ousterhout <ouster@eng.sun.com>
* Jon Biggar <jon@netlabs.com>
* Malcolm Beattie <mbeattie@sable.ox.ac.uk>
* Michael D'Errico <mike@software.com>
* Randal Schwartz <merlyn@stonehenge.com>
* Roberto Salama <rs@fi.gs.com>
* Steven L Kunz <skunz@iastate.edu>
* Theodore C. Law <TEDLAW@TOROLAB6.VNET.IBM.COM>
* Thomas R. Kimpton <tom@dtint.dtint.com>
* Timothy Murphy <tim@maths.tcd.ie>
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 3/5 - Programming Aids
Message-ID: <perl-faq/part3_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 3/5 - Programming Aids
Supersedes: <perl-faq/part3_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:38 GMT
Organization: none
Lines: 424
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part3_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39238 comp.answers:8355
news.answers:32282
Archive-name: perl-faq/part3
Version: $Id: part3,v 2.1 1994/10/25 13:56:19 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to general information questions, mostly
about programming aids.
3.1) How can I use Perl interactively?
The easiest way to do this is to run Perl under its debugger. If
you
have no program to debug, you can invoke the debugger on an
`empty'
program like this:
perl -de 0
(The more positive hackers prefer "perl -de 1". :-)
Now you can type in any legal Perl code, and it will be
immediately
evaluated. You can also examine the symbol table, get stack
backtraces, check variable values, and if you want to, set
breakpoints
and do the other things you can do in a symbolic debugger.
3.2) Is there a Perl profiler?
While there isn't one included with the perl source distribution
(yet)
various folks have written packages that allow you to do at least
some
sort of profiling. The strategy usually includes modifying the
perl
debugger to handle profiling. Authors of these packages include
Wayne Thompson <me@anywhere.EBay.Sun.COM>
Ray Lischner <lisch@sysserver1.mentor.com>
Kresten Krab Thorup <krab@iesd.auc.dk>
The original articles by these folks containing their profilers
are
available on convex.com in /pub/perl/information/profiling.shar
via
anon ftp.
3.3) Is there a yacc for Perl?
Yes!! It's a version of Berkeley yacc that outputs Perl code
instead
of C code! You can get this from ftp.sterling.com [192.124.9.1]
in
/local/perl-byacc1.8.1.tar.Z, or send the author mail for details.
3.4) Is there a pretty-printer for Perl?
That depends on what you mean. If you want something that works
like
vgrind on Perl programs, then the answer is "yes, nearly". Here's
a
vgrind entry for perl:
PERL|perl|Perl:\
:pb=^\d?(sub|package)\d\p\d:\
:bb={:be=}:cb=#:ce=$:sb=":se=\e":lb=':\
:le=\e':tl:\
:id=_:\
:kw=\
if for foreach unless until while continue else elsif \
do eval require \
die exit \
defined delete reset \
goto last redo next dump \
local undef return \
write format \
sub package
It doesn't actually do everything right; in particular,
things like $#, $', s#/foo##, and $foo'bar all confuse it.
David Levine uses this:
# perl 4.x David Levine <levine@ics.uci.edu> 05
apr
1993
# Derived from Tom Christiansen's perl vgrindef. I'd like to
treat all
of
# perl's built-ins as keywords, but vgrind fields are limited
to
1024
# characters and the built-ins overflow that (surprise :-). So,
I
didn't
# include the dbm*, end*, get*, msg*, sem*, set*, and shm*
functions.
I
# couldn't come up with an easy way to distinguish beginnings of
literals
# ('...') from package prefixes, so literals are not marked.
# Be sure to:
# 1) include whitespace between a subprogram name and its opening
{
# 2) include whitespace before a comment (so that $# doesn't get
# interpreted as one).
perl4:\
:pb=^\d?(sub|package)\d\p\d:\
:id=$%@_:\
:bb=\e{:be=\e}:cb=\d\e#:ce=$:sb=\e":se=\e":\
:kw=accept alarm atan2 bind binmode caller chdir chmod chop \
chown chroot close closedir connect continue cos crypt defined
delete \
die do dump each else elsif eof eval exec exit exp fcntl fileno
flock \
for foreach fork format getc gmtime goto grep hex if include index
int \
ioctl join keys kill last length link listen local localtime log
lstat \
m mkdir next oct open opendir ord pack package pipe pop print
printf \
push q qq qx rand read readdir readlink recv redo rename require
reset \
return reverse rewinddir rindex rmdir s scalar seek seekdir select
send \
shift shutdown sin sleep socket socketpair sort splice split
sprintf \
sqrt srand stat study sub substr symlink syscall sysread system \
syswrite tell telldir time times tr truncate umask undef unless
unlink \
unpack unshift until utime values vec wait waitpid wantarray warn
while \
write y:
If what you mean is whether there is a program that will reformat
the
program much as indent(1) will do for C, then the answer is no.
The
complex feedback between the scanner and the parser (as in the
things
that confuse vgrind) make it challenging at best to write a stand-
alone
Perl parser.
3.5) There's an a2p and an s2p; why isn't there a p2c (perl-to-C)?
Because the Pascal people would be upset that we stole their name.
:-)
The dynamic nature of Perl's do and eval operators (and remember
that
constructs like s/$mac_donald/$mac_gregor/eieio count as an eval)
would
make this very difficult. To fully support them, you would have
to put
the whole Perl interpreter into each compiled version for those
scripts
using them. This is what undump does right now, if your machine
has it.
If what you're doing will be faster in C than in Perl, maybe it
should
have been written in C in the first place. For things that ought
to be
written in Perl, the interpreter will be just about as fast,
because the
pattern matching routines won't work any faster linked into a C
program.
Even in the case of simple Perl programs that don't do any fancy
evals,
the
major gain would be in compiling the control flow tests, with the
rest
still being a maze of twisty, turny subroutine calls. Since these
are not
usually the major bottleneck in the program, there's not as much
to be
gained via compilation as one might think.
However, we're still looking for someone to generate byte-compiled
code for Perl, or eventually even C code out of it. These are
probably masters and PhD thesis topics respectively, and no one
has begun work on it yet.
3.6) Where can I get a perl-mode for emacs?
Since Emacs version 19 patchlevel 22 or so, there has been both a
perl-mode.el and support for the perl debugger built in. These
should
come with the standard Emacs 19 distribution.
In the perl source directory, you'll find a directory called
"emacs", which contains several files that should help you.
3.7) Is there a Perl shell?
Not really. Perl is a programming language, not a command
interpreter. There is a very simple one called "perlsh"
included in the Perl source distribution. It just does this:
$/ = ''; # set paragraph mode
$SHlinesep = "\n";
while ($SHcmd = <>) {
$/ = $SHlinesep;
eval $SHcmd; print $@ || "\n";
$SHlinesep = $/; $/ = '';
}
Not very interesting, eh?
Daniel Smith <dansmith@autodesk.com> is working on an interactive
Perl
shell called SoftList. It's currently at version 3.0beta.
SoftList
3.0 has tcsh-like command line editing, can let you define a file
of
aliases so that you can run chunks of perl or UNIX commands, and
so
on. You can send mail to him for further information and
availability.
3.8) How can I use curses with perl?
In release 4 of perl, the only way to do this was was to build a
curseperl binary by linking in your C curses library as described
in
the usub subdirectory of the perl sources. This requires a
modicum of
work, but it will be reasonably fast since it's all in C (assuming
you
consider curses reasonably fast. :-) Programs written using this
method require the modified curseperl, not vanilla perl, to run.
While this is something of a disadvantage, experience indicates
that
it's better to use curseperl than to try to roll your own using
termcap directly.
Fortunately, in version 5, Curses is a dynamically loaded
extension
by William Setzer*. You should be able to pick it up wherever you
get Perl 5 from, or at least these places:
ftp://ftp.ncsu.edu/pub/math/wsetzer/cursperl5a6.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/cursperl5a6.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/cursperl5a6.tar.gz
For a good example of using (v4) curseperl, you might want to pick
up a
copy of Steven L Kunz's* "perl menus" package ("menu.pl") via
anonymous FTP from "ftp.iastate.edu". It's in the /pub/perl as
menu.pl.v2.3.shr1
menu.pl.v2.3.shr2
menu.pl.v2.3.tar.Z
menus.pl is a complete menu front-end for curseperl and
demonstates
a lot of things (plus it is useful to boot if you want full-screen
menu selection ability).
Another possibility is to use Henk Penning's cterm package, a
curses
emulation library written in perl. cterm is actually a separate
program with which you communicate via a pipe. It is available
from
ftp.cs.ruu.nl [131.211.80.17] via anonymous ftp. in the directory
pub/PERL. You may also acquire the package via email in
compressed,
uuencoded form by sending a message to mail-server@cs.ruu.nl
containing these lines:
begin
send PERL/cterm.shar.Z
end
See the question on retrieving perl via mail for more information
on
how to retrieve other items of interest from the mail server
there.
3.9) How can I use X with Perl?
Right now, you have several choices. If you are still using
perl4, use
the WAFE or STDWIN packages, or try to make your own usub binding.
However, if you've upgraded to version 5, you have several
exciting
possibilities, with more popping up each day. Right now, Tk and
Sx
are the best known such extensions.
If you like the tk package, you should get the Tk extension kit,
written by Malcolm Beattie*. Here are some places to get it:
Tk (as in tcl/tk, but sans tcl)
ftp://ftp.cis.ufl.edu/pub/perl/src/tkperl/tkperl5a4.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/tkperl5a4.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/tkperl/tkperl5a4.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/tkperl5a4.tar.gz
ftp://black.ox.ac.uk/src/ALPHA/tkperl5a4.tar.gz
(try 5a5 everywhere after 2pm UST Thu 20 Oct 1994, as in)
ftp://sable.ox.ac.uk/pub/perl/tkperl5a5.tar.gz
You may also use the old Sx package, (Athena & Xlib), written by
originally written by by Dominic Giampaolo*, then and rewritten
for Sx
by Frederic Chauveau*.fr>. It's available from these sites:
ftp://ftp.pasteur.fr/pub/Perl/Sx.tar.gz
ftp://ftp.khoros.unm.edu/pub/perl/extensions/Sx.tar.gz
ftp://ftp.metronet.com/pub/perlinfo/perl5/Sx.tar.gz
ftp://ftp.cs.ruu.nl/pub/PERL/perl5.0/PerlDoc.ps.gz
STDWIN is a library written by Guido van Rossum* (author of the
Python
programming language) that is portable between Mac, Dos and X11.
One
could write a Perl agent to speak to this STDWIN server.
WAFE is a package that implements a symbolic interface to the
Athena
widgets (X11R5). A typical Wafe application consists in our
framework
of two parts: the front-end (we call it Wafe for
Widget[Athena]front
end) and an application program running typically as a separate
process. The application program can be implemented in an
arbitrary
programming language and talks to the front-end via stdio. Since
Wafe
(the front-end) was developed using the extensible TCL shell (cite
John
Ousterhout), an application program can dynamically submit
requests to
the front-end to build up the graphical user interface; the
application can even down-load application specific procedures
into
the front-end. The distribution contains sample application
programs
in Perl, GAWK, Prolog, TCL, and C talking to the same Wafe binary.
Many of the demo applications are implemented in Perl. Wafe 0.9
can
be obtained via anonymous ftp from
ftp.wu-wien.ac.at[137.208.3.5]:pub/src/X11/wafe-0.9.tar.Z
Alternatively, you could use wish from tcl.
#!/usr/local/bin/perl
#####################################################################
# An example of calling wish as a subshell under Perl and
# interactively communicating with it through sockets.
#
# The script is directly based on Gustaf Neumann's perlwafe
script.
#
# Dov Grobgeld dov@menora.weizmann.ac.il
# 1993-05-17
#####################################################################
$wishbin = "/usr/local/bin/wish";
die "socketpair unsuccessful: $!!\n" unless
socketpair(W0,WISH,1,1,0);
if ($pid=fork) {
select(WISH); $| = 1;
select(STDOUT);
# Create some TCL procedures
print WISH 'proc echo {s} {puts stdout $s; flush stdout}',"\n";
# Create the widgets
print WISH <<TCL;
# This is a comment "inside" wish
frame .f -relief raised -border 1 -bg green
pack append . .f {top fill expand}
button .f.button-pressme -text "Press me" -command {
echo "That's nice."
}
button .f.button-quit -text quit -command {
echo "quit"
}
pack append .f .f.button-pressme {top fill expand} \\
.f.button-quit {top expand}
TCL
;
# Here is the main loop which receives and sends commands
# to wish.
while (<WISH>) {
chop;
print "Wish sais: <$_>\n";
if (/^quit/) { print WISH "destroy .\n"; last; }
}
wait;
} elsif (defined $pid) {
open(STDOUT, ">&W0");
open(STDIN, ">&W0");
close(W0);
select(STDOUT); $| = 1;
exec "$wishbin --";
} else {
die "fork error: $!\n";
}
3.10) Can I dynamically load C user routines?
Yes -- dynamic loading comes with the distribution. That means
that
you no longer need 18 different versions of fooperl floating
around.
In fact, all of perl can be stuck into a libperl.so library and
then your /usr/local/bin/perl binary reduced to just 50k or so.
See DynLoader(3pm) for details.
In perl4, the answer is kinda. One package has been released that
does
this, by Roberto Salama*. He writes:
Here is a version of dylperl, dynamic linker for perl. The code
here is
based on Oliver Sharp's May 1993 article in Dr. Dobbs Journal
(Dynamic
Linking under Berkeley UNIX).
dyl.h
dyl.c - code extracted from Oliver Sharp's article
hash.h
hash.c - Berkeley's hash functions, should use perl's but
could not be bothered
dylperl.c - perl usersubs
user.c - userinit function
sample.c - sample code to be dyl'ed
sample2.c - "
test.pl - sample perl script that dyl's sample*.o
The Makefile assumes that uperl.o is in /usr/local/src/perl/...
You
will probable have to change this to reflect your installation.
Other
than that, just type 'make'...
The idea behind being able to dynamically link code into perl is
that
the linked code should become perl functions, i.e. they can be
invoked
as &foo(...). For this to happen, the incrementally loaded code
must
use the perl stack, look at sample.c to get a better idea.
The few functions that make up this package are outlined below.
&dyl("file.o"): dynamically link file.o. All functions and non-
static
variables become visible from within perl. This
function returns a pointer to an internal hash table
úÿ
corresponding to the symbol table of the newly loaded
code.
eg: $ht = &dyl("sample.o")
This function can also be called with the -L and -l ld options.
eg: $ht = &dyl(""sample2.o", "-L/usr/lib", "-lm")
will also pick up the math library if sample.o
accesses any symbols there.
&dyl_find("func"): find symbol 'func' and return its symbol table
entry
&dyl_functions($ht): print the contents of the internal hash table
&dyl_print_symbols($f): prints the contents of the symbol returned
by
dyl_find()
There is very little documentation, maybe something to do for a
future
release. The files sample.o, and sample2.o contain code to be
incrementally loaded, test.pl is the test perl script.
Comments are welcome. I submit this code for public consumption
and,
basically, am not responsible for it in any way.
3.11) What is undump and where can I get it?
The undump program comes from the TeX distribution. If you have
TeX,
then you may have a working undump. If you don't, and you can't
get
one, *AND* you have a GNU emacs working on your machine that can
clone
itself, then you might try taking its unexec() function and
compiling
Perl with -DUNEXEC, which will make Perl call unexec() instead of
abort(). You'll have to add unexec.o to the objects line in the
Makefile. If you succeed, post to comp.lang.perl about your
experience
so others can benefit from it.
If you have a version of undump that works with Perl, please
submit
its anon-FTP whereabouts to the FAQ maintainer.
3.12) How can I get '#!perl' to work under MS-DOS?
John Dallman* has written a program "#!perl.exe" which will do
this.
It is available through anonymous ftp from ftp.ee.umanitoba.ca in
the
directory /pub/msdos/perl/hbp_20.zip. This program works by
finding
the script and perl.exe, building a command line and running
perl.exe
as a child process. For more information on this, contact John
directly.
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 4/5 - General Programming
Message-ID: <perl-faq/part4_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 4/5 - General Programming
Supersedes: <perl-faq/part4_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:53 GMT
Organization: none
Lines: 1065
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part4_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39241 comp.answers:8358
news.answers:32285
Archive-name: perl-faq/part4
Version: $Id: part4,v 2.3 1994/11/07 18:06:47 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to the following questions about General
Programming, Regular Expressions (Regexp) and Input/Output:
4.1) What are all these $@%*<> signs and how do I know when to use
them?
Those are type specifiers:
$ for scalar values
@ for indexed arrays
% for hashed arrays (associative arrays)
* for all types of that symbol name. These are sometimes used like
pointers
<> are used for inputting a record from a filehandle.
See the question on arrays of arrays for more about Perl pointers.
While there are a few places where you don't actually need these
type
specifiers, except for files, you should always use them. Note
that
<FILE> is NOT the type specifier for files; it's the equivalent of
awk's
getline function, that is, it reads a line from the handle FILE.
When
doing open, close, and other operations besides the getline
function on
files, do NOT use the brackets.
Beware of saying:
$foo = BAR;
Which wil be interpreted as
$foo = 'BAR';
and not as
$foo = <BAR>;
If you always quote your strings, you'll avoid this trap.
Normally, files are manipulated something like this (with
appropriate
error checking added if it were production code):
open (FILE, ">/tmp/foo.$$");
print FILE "string\n";
close FILE;
If instead of a filehandle, you use a normal scalar variable with
file
manipulation functions, this is considered an indirect reference
to a
filehandle. For example,
$foo = "TEST01";
open($foo, "file");
After the open, these two while loops are equivalent:
while (<$foo>) {}
while (<TEST01>) {}
as are these two statements:
close $foo;
close TEST01;
but NOT to this:
while (<$TEST01>) {} # error
^
^ note spurious dollar sign
This is another common novice mistake; often it's assumed that
open($foo, "output.$$");
will fill in the value of $foo, which was previously undefined.
This
just isn't so -- you must set $foo to be the name of a filehandle
before you attempt to open it.
4.2) How come Perl operators have different precedence than C
operators?
Actually, they don't; all C operators have the same precedence in
Perl as
they do in C. The problem is with a class of functions called
list
operators, e.g. print, chdir, exec, system, and so on. These are
somewhat
bizarre in that they have different precedence depending on
whether you
look on the left or right of them. Basically, they gobble up all
things
on their right. For example,
unlink $foo, "bar", @names, "others";
will unlink all those file names. A common mistake is to write:
unlink "a_file" || die "snafu";
The problem is that this gets interpreted as
unlink("a_file" || die "snafu");
To avoid this problem, you can always make them look like function
calls
or use an extra level of parentheses:
unlink("a_file") || die "snafu";
(unlink "a_file") || die "snafu";
In perl5, there are low precedence "and", "or", and "not"
operators,
which bind les tightly than comma. This alllows you to write:
unlink $foo, "bar", @names, "others" or die "snafu";
Sometimes you actually do care about the return value:
unless ($io_ok = print("some", "list")) { }
Yes, print() returns I/O success. That means
$io_ok = print(2+4) * 5;
returns 5 times whether printing (2+4) succeeded, and
print(2+4) * 5;
returns the same 5*io_success value and tosses it.
See the perlop(1) man page's section on Precedence for more gory
details,
and be sure to use the -w flag to catch things like this.
4.3) What's the difference between dynamic and static (lexical)
scoping?
What are my() and local()?
[NOTE: This question refers to perl5 only. There is no my() in
perl4]
Scoping refers to visibility of variables. A dynamic variable is
created via local() and is just a local value for a global
variable,
whereas a lexical variable created via my() is more what you're
expecting from a C auto. (See also "What's the difference between
deep and shallow binding.") In general, we suggest you use
lexical
variables wherever possible, as they're faster to access and
easier to
understand. The "use strict vars" pragma will enforce that all
variables are either lexical, or full classified by package name.
We
strongly suggest that you develop your code with "use strict;" and
the
-w flag. (When using formats, however, you will still have to use
dynamic variables.) Here's an example of the difference:
$scount = 1; $lcount = 2;
sub foo {
my($i,$j) = @_;
my $scount = 10;
local $lcount = 20;
&bar();
}
sub bar {
print "scount is $scount\en";
print "lcount is $lcount\en";
}
This prints:
scount is 1
lcount is 20
Notice that the variables declared with my() are visible only
within
the scope of the block which names them. They are not visible
outside
of this block, not even in routines or blocks that it calls.
local()
variables, on the other hand, are visible to routines that are
called
from the block where they are declared. Neither is visible after
the
end (the final closing curly brace) of the block at all.
Oh, lexical variables are only available in perl5. Have we
mentioned yet that you might consider upgrading? :-)
4.4) What's the difference between deep and shallow binding?
This only matters when you're making subroutines yourself, at
least
so far. This will give you shallow binding:
{
my $x = time;
$coderef = sub { $x };
}
When you call &$coderef(), it will get whatever dynamic $x happens
to be around when invoked. However, you can get the other
behaviour
this way:
{
my $x = time;
$coderef = eval "sub { \$x }";
}
Now you'll access the lexical variable $x which is set to the
time the subroutine was created. Note that the difference in
these
two behaviours can be considered a bug, not a feature, so you
should
in particular not rely upon shallow binding, as it will likely go
away in the future. See perlref(1).
4.5) How can I manipulate fixed-record-length files?
The most efficient way is using pack and unpack. This is faster
than
using substr. Here is a sample chunk of code to break up and put
back
together again some fixed-format input lines, in this case, from
ps.
# sample input line:
# 15158 p5 T 0:00 perl /mnt/tchrist/scripts/now-what
$ps_t = 'A6 A4 A7 A5 A*';
open(PS, "ps|");
$_ = <PS>; print;
while (<PS>) {
($pid, $tt, $stat, $time, $command) = unpack($ps_t, $_);
for $var ('pid', 'tt', 'stat', 'time', 'command' ) {
print "$var: <", eval "\$$var", ">\n";
}
print 'line=', pack($ps_t, $pid, $tt, $stat, $time, $command),
"\n";
}
4.6) How can I make a file handle local to a subroutine?
You must use the type-globbing *VAR notation. Here is some code
to
cat an include file, calling itself recursively on nested local
include files (i.e. those with #include "file", not #include
<file>):
sub cat_include {
local($name) = @_;
local(*FILE);
local($_);
warn "<INCLUDING $name>\n";
if (!open (FILE, $name)) {
warn "can't open $name: $!\n";
return;
}
while (<FILE>) {
if (/^#\s*include "([^"]*)"/) {
&cat_include($1);
} else {
print;
}
}
close FILE;
}
4.7) How can I call alarm() or usleep() from Perl?
If you want finer granularity than 1 second (as usleep() provides)
and
have itimers and syscall() on your system, you can use the
following.
You could also use select().
It takes a floating-point number representing how long to delay
until
you get the SIGALRM, and returns a floating- point number
representing
how much time was left in the old timer, if any. Note that the C
function uses integers, but this one doesn't mind fractional
numbers.
# alarm; send me a SIGALRM in this many seconds (fractions ok)
# tom christiansen <tchrist@convex.com>
sub alarm {
require 'syscall.ph';
require 'sys/time.ph';
local($ticks) = @_;
local($in_timer,$out_timer);
local($isecs, $iusecs, $secs, $usecs);
local($itimer_t) = 'L4'; # should be &itimer'typedef()
$secs = int($ticks);
$usecs = ($ticks - $secs) * 1e6;
$out_timer = pack($itimer_t,0,0,0,0);
$in_timer = pack($itimer_t,0,0,$secs,$usecs);
syscall(&SYS_setitimer, &ITIMER_REAL, $in_timer, $out_timer)
&& die "alarm: setitimer syscall failed: $!";
($isecs, $iusecs, $secs, $usecs) = unpack($itimer_t,$out_timer);
return $secs + ($usecs/1e6);
}
4.8) How can I do an atexit() or setjmp()/longjmp() in Perl?
(Exception
handling)
Perl's exception-handling mechanism is its eval operator. You
can use eval as setjmp and die as longjmp. Here's an example
of Larry's for timed-out input, which in C is often implemented
using setjmp and longjmp:
$SIG{ALRM} = TIMEOUT;
sub TIMEOUT { die "restart input\n" }
do { eval { &realcode } } while $@ =~ /^restart input/;
sub realcode {
alarm 15;
$ans = <STDIN>;
alarm 0;
}
Here's an example of Tom's for doing atexit() handling:
sub atexit { push(@_exit_subs, @_) }
sub _cleanup { unlink $tmp }
&atexit('_cleanup');
eval <<'End_Of_Eval'; $here = __LINE__;
# as much code here as you want
End_Of_Eval
$oops = $@; # save error message
# now call his stuff
for (@_exit_subs) { &$_() }
$oops && ($oops =~ s/\(eval\) line (\d+)/$0 .
" line " . ($1+$here)/e, die $oops);
You can register your own routines via the &atexit function now.
You
might also want to use the &realcode method of Larry's rather than
embedding all your code in the here-is document. Make sure to
leave
via die rather than exit, or write your own &exit routine and call
that instead. In general, it's better for nested routines to
exit
via die rather than exit for just this reason.
In Perl5, it is easy to set this up because of the automatic
processing
of per-package END functions.
Eval is also quite useful for testing for system dependent
features,
like symlinks, or using a user-input regexp that might otherwise
blowup on you.
4.9) How do I catch signals in perl?
Perl allows you to trap signals using the %SIG associative array.
Using the signals you want to trap as the key, you can assign a
subroutine to that signal. The %SIG array will only contain those
values which the programmer defines. Therefore, you do not have
to
assign all signals. For example, to exit cleanly from a ^C:
$SIG{'INT'} = 'CLEANUP';
sub CLEANUP {
print "\n\nCaught Interrupt (^C), Aborting\n";
exit(1);
}
There are two special "routines" for signals called DEFAULT and
IGNORE.
DEFAULT erases the current assignment, restoring the default value
of
the signal. IGNORE causes the signal to be ignored. In general,
you
don't need to remember these as you can emulate their
functionality
with standard programming features. DEFAULT can be emulated by
deleting the signal from the array and IGNORE can be emulated by
any
undeclared subroutine.
4.10) Why doesn't Perl interpret my octal data octally?
Perl only understands octal and hex numbers as such when they
occur
as literals in your program. If they are read in from somewhere
and
assigned, then no automatic conversion takes place. You must
explicitly use oct() or hex() if you want this kind of thing to
happen.
Actually, oct() knows to interpret both hex and octal numbers,
while
hex only converts hexadecimal ones. For example:
{
print "What mode would you like? ";
$mode = <STDIN>;
$mode = oct($mode);
unless ($mode) {
print "You can't really want mode 0!\n";
redo;
}
chmod $mode, $file;
}
Without the octal conversion, a requested mode of 755 would turn
into 01363, yielding bizarre file permissions of --wxrw--wt.
If you want something that handles decimal, octal and hex input,
you could follow the suggestion in the man page and use:
$val = oct($val) if $val =~ /^0/;
úÿ
4.11) How can I compare two date strings?
If the dates are in an easily parsed, predetermined format, then
you
can break them up into their component parts and call &timelocal
from
the distributed perl library. If the date strings are in
arbitrary
formats, however, it's probably easier to use the getdate program
from
the Cnews distribution, since it accepts a wide variety of dates.
Note
that in either case the return values you will really be comparing
will
be the total time in seconds as returned by time().
Here's a getdate function for perl that's not very efficient; you
can
do better than this by sending it many dates at once or modifying
getdate to behave better on a pipe. Beware the hardcoded
pathname.
sub getdate {
local($_) = shift;
s/-(\d{4})$/+$1/ || s/\+(\d{4})$/-$1/;
# getdate has broken timezone sign reversal!
$_ = `/usr/local/lib/news/newsbin/getdate '$_'`;
chop;
$_;
}
Richard Ohnemus <Rick_Ohnemus@Sterling.COM> actually has a
getdate.y for
use with the Perl yacc. You can get this from ftp.sterling.com
[192.124.9.1] in /local/perl-byacc1.8.1.tar.Z, or send the author
for details.
You might also consider using these:
date.pl - print dates how you want with the sysv +FORMAT
method
date.shar - routines to manipulate and calculate dates
ftp-chat2.shar - updated version of ftpget. includes library and
demo
programs
getdate.shar - returns number of seconds since epoch for any
given
date
ptime.shar - print dates how you want with the sysv +FORMAT
method
You probably want 'getdate.shar'... these and other files can be
ftp'd
from the /pub/perl/scripts directory on ftp.cis.ufl.edu. See the
README
file in the /pub/perl directory for time and the European mirror
site
details.
4.12) How can I find the Julian Day?
Here's an example of a Julian Date function provided by Thomas R.
Kimpton*.
#!/usr/local/bin/perl
@theJulianDate = ( 0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
304, 334
);
#*********************************************************************
***
#**** Return 1 if we are after the leap day in a leap year.
*****
#*********************************************************************
***
sub leapDay
{
my($year,$month,$day) = @_;
if (year % 4) {
return(0);
}
if (!(year % 100)) { # years that are multiples of
100
# are not leap years
if (year % 400) { # unless they are multiples of 400
return(0);
}
}
if (month < 2) {
return(0);
} elsif ((month == 2) && (day < 29)) {
return(0);
} else {
return(1);
}
}
#*********************************************************************
***
#**** Pass in the date, in seconds, of the day you want the
*****
#**** julian date for. If your localtime() returns the year day
*****
#**** return that, otherwise figure out the julian date.
*****
#*********************************************************************
***
sub julianDate
{
my($dateInSeconds) = @_;
my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) =
localtime($dateInSeconds);
if (defined($yday)) {
return($yday+1);
} else {
return($theJulianDate[$mon] + $mday +
&leapDay($year,$mon,$mday));
}
}
print "Today's julian date is: ",&julianDate(time),"\n";
4.13) What's the fastest way to code up a given task in perl?
Post it to comp.lang.perl and ask Tom or Randal a question about
it.
;)
Because Perl so lends itself to a variety of different approaches
for
any given task, a common question is which is the fastest way to
code a
given task. Since some approaches can be dramatically more
efficient
that others, it's sometimes worth knowing which is best.
Unfortunately, the implementation that first comes to mind,
perhaps as
a direct translation from C or the shell, often yields suboptimal
performance. Not all approaches have the same results across
different
hardware and software platforms. Furthermore, legibility must
sometimes be sacrificed for speed.
While an experienced perl programmer can sometimes eye-ball the
code
and make an educated guess regarding which way would be fastest,
surprises can still occur. So, in the spirit of perl programming
being an empirical science, the best way to find out which of
several
different methods runs the fastest is simply to code them all up
and
time them. For example:
$COUNT = 10_000; $| = 1;
print "method 1: ";
($u, $s) = times;
for ($i = 0; $i < $COUNT; $i++) {
# code for method 1
}
($nu, $ns) = times;
printf "%8.4fu %8.4fs\n", ($nu - $u), ($ns - $s);
print "method 2: ";
($u, $s) = times;
for ($i = 0; $i < $COUNT; $i++) {
# code for method 2
}
($nu, $ns) = times;
printf "%8.4fu %8.4fs\n", ($nu - $u), ($ns - $s);
Perl5 includes a new module called Benchmark.pm. You can now
simplify
the code to use the Benchmarking, like so:
use Benchmark;
timethese($count, {
Name1 => '...code for method 1...',
Name2 => '...code for method 2...',
... });
It will output something that looks similar to this:
Benchmark: timing 100 iterations of Name1, Name2...
Name1: 2 secs (0.50 usr 0.00 sys = 0.50 cpu)
Name2: 1 secs (0.48 usr 0.00 sys = 0.48 cpu)
For example, the following code will show the time difference
between
three different ways of assigning the first character of a string
to
a variable:
use Benchmark;
timethese(100000, {
'regex1' => '$str="ABCD"; $str =~ s/^(.)//; $ch = $1',
'regex2' => '$str="ABCD"; $str =~ s/^.//; $ch = $&',
'substr' => '$str="ABCD"; $ch=substr($str,0,1);
substr($str,0,1)="",
});
The results will be returned like this:
Benchmark: timing 100000 iterations of regex1, regex2, substr...
regex1: 11 secs (10.80 usr 0.00 sys = 10.80 cpu)
regex2: 10 secs (10.23 usr 0.00 sys = 10.23 cpu)
substr: 7 secs ( 5.62 usr 0.00 sys = 5.62 cpu)
For more specific tips, see the section on Efficiency in the
``Other Oddments'' chapter at the end of the Camel Book.
4.14) Do I always/never have to quote my strings or use semicolons?
You don't have to quote strings that can't mean anything else in
the
language, like identifiers with any upper-case letters in them.
Therefore, it's fine to do this:
$SIG{INT} = Timeout_Routine;
or
@Days = (Sun, Mon, Tue, Wed, Thu, Fri, Sat, Sun);
but you can't get away with this:
$foo{while} = until;
in place of
$foo{'while'} = 'until';
The requirements on semicolons have been increasingly relaxed.
You no
longer need one at the end of a block, but stylistically, you're
better
to use them if you don't put the curly brace on the same line:
for (1..10) { print }
is ok, as is
@nlist = sort { $a <=> $b } @olist;
but you probably shouldn't do this:
for ($i = 0; $i < @a; $i++) {
print "i is $i\n" # <-- oops!
}
because you might want to add lines later, and anyway, it looks
funny. :-)
4.15) What is variable suicide and how can I prevent it?
Variable suicide is a nasty side effect of dynamic scoping and the
way
variables are passed by reference. If you say
$x = 17;
&munge($x);
sub munge {
local($x);
local($myvar) = $_[0];
...
}
Then you have just clobbered $_[0]! Why this is occurring is
pretty
heavy wizardry: the reference to $x stored in $_[0] was
temporarily
occluded by the previous local($x) statement (which, you're
recall,
occurs at run-time, not compile-time). The work around is simple,
however: declare your formal parameters first:
sub munge {
local($myvar) = $_[0];
local($x);
...
}
That doesn't help you if you're going to be trying to access @_
directly after the local()s. In this case, careful use of the
package
facility is your only recourse.
Another manifestation of this problem occurs due to the magical
nature
of the index variable in a foreach() loop.
@num = 0 .. 4;
print "num begin @num\n";
foreach $m (@num) { &ug }
print "num finish @num\n";
sub ug {
local($m) = 42;
print "m=$m $num[0],$num[1],$num[2],$num[3]\n";
}
Which prints out the mysterious:
num begin 0 1 2 3 4
m=42 42,1,2,3
m=42 0,42,2,3
m=42 0,1,42,3
m=42 0,1,2,42
m=42 0,1,2,3
num finish 0 1 2 3 4
What's happening here is that $m is an alias for each element of
@num.
Inside &ug, you temporarily change $m. Well, that means that
you've
also temporarily changed whatever $m is an alias to!! The only
workaround is to be careful with global variables, using packages,
and/or just be aware of this potential in foreach() loops.
The perl5 static autos via "my" will not have this problem.
4.16) What does "Malformed command links" mean?
This is a bug in 4.035. While in general it's merely a cosmetic
problem, it often comanifests with a highly undesirable
coredumping
problem. Programs known to be affected by the fatal coredump
include
plum and pcops. This bug has been fixed since 4.036. It did not
resurface in 5.000.
4.17) How can I set up a footer format to be used with write()?
While the $^ variable contains the name of the current header
format,
there is no corresponding mechanism to automatically do the same
thing
for a footer. Not knowing how big a format is going to be until
you
evaluate it is one of the major problems.
If you have a fixed-size footer, you can get footers by checking
for
line left on page ($-) before each write, and printing the footer
yourself if necessary.
Another strategy is to open a pipe to yourself, using open(KID, "|-
")
and always write()ing to the KID, who then postprocesses its STDIN
to
rearrange headers and footers however you like. Not very
convenient,
but doable.
4.18) Why does my Perl program keep growing in size?
This is caused by a strange occurance that Larry has dubbed
"feeping
creaturism". Larry is always adding one more feature, always
getting
Perl to handle one more problem. Hence, it keeps growing. Once
you've
worked with perl long enough, you will probably start to do the
same
thing. You will then notice this problem as you see your scripts
becoming larger and larger.
Oh, wait... you meant a currently running program and it's stack
size.
Mea culpa, I misunderstood you. ;) While there may be a real
memory
leak in the Perl source code or even whichever malloc() you're
using,
common causes are incomplete eval()s or local()s in loops.
An eval() which terminates in error due to a failed parsing will
leave
a bit of memory unusable.
A local() inside a loop:
for (1..100) {
local(@array);
}
will build up 100 versions of @array before the loop is done. The
work-around is:
local(@array);
for (1..100) {
undef @array;
}
Larry reports that this behavior is fixed for perl5.
4.19) Can I do RPC in Perl?
Yes, you can, since Perl has access to sockets. An example of the
rup
program written in Perl can be found in the script ruptime.pl at
the
scripts archive on ftp.cis.ufl.edu. I warn you, however, that
it's not
a pretty sight, as it's used nothing from h2ph or c2ph, so
everything is
utterly hard-wired.
4.20) How can I quote a variable to use in a regexp?
From the manual:
$pattern =~ s/(\W)/\\$1/g;
Now you can freely use /$pattern/ without fear of any unexpected
meta-
characters in it throwing off the search. If you don't know
whether a
pattern is valid or not, enclose it in an eval to avoid a fatal
run-
time error.
Perl5 provides a vastly improved way of doing this. Simply use
the
new quotemeta character (\Q) within your variable.
4.21) How can I change the first N letters of a string?
Remember that the substr() function produces an lvalue, that is,
it may
be assigned to. Therefore, to change the first character to an S,
you
could do this:
substr($var,0,1) = 'S';
This assumes that $[ is 0; for a library routine where you can't
know
$[, you should use this instead:
substr($var,$[,1) = 'S';
While it would be slower, you could in this case use a substitute:
$var =~ s/^./S/;
But this won't work if the string is empty or its first character
is a
newline, which "." will never match. So you could use this
instead:
$var =~ s/^[^\0]?/S/;
To do things like translation of the first part of a string, use
substr, as in:
substr($var, $[, 10) =~ tr/a-z/A-Z/;
If you don't know the length of what to translate, something like
this
works:
/^(\S+)/ && substr($_,$[,length($1)) =~ tr/a-z/A-Z/;
úÿ
For some things it's convenient to use the /e switch of the
substitute
operator:
s/^(\S+)/($tmp = $1) =~ tr#a-z#A-Z#, $tmp/e
although in this case, it runs more slowly than does the previous
example.
4.22) Can I use Perl regular expressions to match balanced text?
No, or at least, not by the themselves.
Regexps just aren't powerful enough. Although Perl's patterns
aren't
strictly regular because they do backreferencing (the \1
notation), you
still can't do it. You need to employ auxiliary logic. A simple
approach would involve keeping a bit of state around, something
vaguely like this (although we don't handle patterns on the same
line):
while(<>) {
if (/pat1/) {
if ($inpat++ > 0) { warn "already saw pat1" }
redo;
}
if (/pat2/) {
if (--$inpat < 0) { warn "never saw pat1" }
redo;
}
}
A rather more elaborate subroutine to pull out balanced and
possibly
nested single chars, like ` and ', { and }, or ( and ) can be
found
on convex.com in /pub/perl/scripts/pull_quotes.
4.23) What does it mean that regexps are greedy? How can I get around
it?
The basic idea behind regexps being greedy is that they will match
the
maximum amount of data that they can, sometimes resulting in
incorrect
or strange answers.
For example, I recently came across something like this:
$_="this (is) an (example) of multiple parens";
while ( m#\((.*)\)#g ) {
print "$1\n";
}
This code was supposed to match everything between a set of
parentheses. The expected output was:
is
example
However, the backreference ($1) ended up containing "is) an
(example",
clearly not what was intended.
In perl4, the way to stop this from happening is to use a negated
group. If the above example is rewritten as follows, the results
are
correct:
while ( m#\(([^)]*)\)#g ) {
In perl5 there is a new minimal matching metacharacter, '?'. This
character is added to the normal metacharacters to modify their
behaviour, such as "*?", "+?", or even "??". The example would
now be
written in the following style:
while (m#\((.*?)\)#g )
Hint: This new operator leads to a very elegant method of
stripping
comments from C code:
s:/\*.*?\*/::gs
4.24) How do I use a regular expression to strip C style comments from
a
file?
Since we're talking about how to strip comments under perl5, now
is a
good time to talk about doing it in perl4. The easiest way to
strip
comments in perl4 is to transform the comment close (*/) into
something
that can't be in the string, or is at least extremely unlikely to
be in
the string. I find \256 (the registered or reserved sign, an R
inside
a circle) is fairly unlikely to be used and is easy to remember.
So,
our code looks something like this:
s:\*/:\256:g; # Change all */ to circled R
s:/\*[^\256]*\256::g; # Remove everything from \* to circled R
print;
To ensure that you correctly handle multi-line comments, don't
forget
to set $* to 1, informing perl that it should do multi-line
pattern
matching.
[Untested changes. If it's wrong or you don't understand it,
check
with Jeff. If it's wrong, let me know so I can change it. ]
Jeff Friedl* suggests that the above solution is incorrect. He
says it
will fail on imbedded comments and function proto-typing as well
as on
comments that are part of strings. The following regexp should
handle
everything:
$/ = undef;
$_ = <>;
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|([^/"']*("[^"\\]*(\\[\d\D][^"\\]*)*"[^/
"']*|'[^
'\\]*(\\[\d\D][^'\\]*)*'[^/"']*|/+[^*/][^/"']*)*)#$2#g;
print;
4.25) Why doesn't "local($foo) = <FILE>;" work right?
Well, it does. The thing to remember is that local() provides an
array
context, and that the <FILE> syntax in an array context will read
all the
lines in a file. To work around this, use:
local($foo);
$foo = <FILE>;
You can use the scalar() operator to cast the expression into a
scalar
context:
local($foo) = scalar(<FILE>);
4.26) How can I detect keyboard input without reading it?
You should check out the Frequently Asked Questions list in
comp.unix.* for things like this: the answer is essentially the
same.
It's very system dependent. Here's one solution that works on BSD
systems:
sub key_ready {
local($rin, $nfd);
vec($rin, fileno(STDIN), 1) = 1;
return $nfd = select($rin,undef,undef,0);
}
4.27) How can I read a single character from the keyboard under UNIX
and DOS?
A closely related question to the no-echo question below is how to
input a single character from the keyboard. Again, this is a
system
dependent operation. The following code may or may not help you.
It
should work on both SysV and BSD flavors of UNIX:
$BSD = -f '/vmunix';
if ($BSD) {
system "stty cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", '-icanon',
system "stty", 'eol', "\001";
}
$key = getc(STDIN);
if ($BSD) {
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", 'icanon';
system "stty", 'eol', '^@'; # ascii null
}
print "\n";
You could also handle the stty operations yourself for speed if
you're
going to be doing a lot of them. This code works to toggle cbreak
and echo modes on a BSD system:
sub set_cbreak { # &set_cbreak(1) or &set_cbreak(0)
local($on) = $_[0];
local($sgttyb,@ary);
require 'sys/ioctl.ph';
$sgttyb_t = 'C4 S' unless $sgttyb_t; # c2ph: &sgttyb'typedef()
ioctl(STDIN,&TIOCGETP,$sgttyb) || die "Can't ioctl TIOCGETP: $!";
@ary = unpack($sgttyb_t,$sgttyb);
if ($on) {
$ary[4] |= &CBREAK;
$ary[4] &= ~&ECHO;
} else {
$ary[4] &= ~&CBREAK;
$ary[4] |= &ECHO;
}
$sgttyb = pack($sgttyb_t,@ary);
ioctl(STDIN,&TIOCSETP,$sgttyb) || die "Can't ioctl TIOCSETP: $!";
}
Note that this is one of the few times you actually want to use
the
getc() function; it's in general way too expensive to call for
normal
I/O. Normally, you just use the <FILE> syntax, or perhaps the
read()
or sysread() functions.
For perspectives on more portable solutions, use anon ftp to
retrieve
the file /pub/perl/info/keypress from convex.com.
For DOS systems, Dan Carson <dbc@tc.fluke.COM> reports:
To put the PC in "raw" mode, use ioctl with some magic numbers
gleaned
from msdos.c (Perl source file) and Ralf Brown's interrupt list
(comes
across the net every so often):
$old_ioctl = ioctl(STDIN,0,0); # Gets device info
$old_ioctl &= 0xff;
ioctl(STDIN,1,$old_ioctl | 32); # Writes it back, setting bit 5
Then to read a single character:
sysread(STDIN,$c,1); # Read a single character
And to put the PC back to "cooked" mode:
ioctl(STDIN,1,$old_ioctl); # Sets it back to cooked mode.
So now you have $c. If ord($c) == 0, you have a two byte code,
which
means you hit a special key. Read another byte
(sysread(STDIN,$c,1)),
and that value tells you what combination it was according to this
table:
# PC 2-byte keycodes = ^@ + the following:
# HEX KEYS
# --- ----
# 0F SHF TAB
# 10-19 ALT QWERTYUIOP
# 1E-26 ALT ASDFGHJKL
# 2C-32 ALT ZXCVBNM
# 3B-44 F1-F10
# 47-49 HOME,UP,PgUp
# 4B LEFT
# 4D RIGHT
# 4F-53 END,DOWN,PgDn,Ins,Del
# 54-5D SHF F1-F10
# 5E-67 CTR F1-F10
# 68-71 ALT F1-F10
# 73-77 CTR LEFT,RIGHT,END,PgDn,HOME
# 78-83 ALT 1234567890-=
# 84 CTR PgUp
This is all trial and error I did a long time ago, I hope I'm
reading the
file that worked.
4.28) How can I get input from the keyboard without it echoing to the
screen?
Terminal echoing is generally handled directly by the shell.
Therefore, there is no direct way in perl to turn echoing on and
off.
However, you can call the command "stty [-]echo". The following
will
allow you to accept input without it being echoed to the screen,
for
example as a way to accept passwords (error checking deleted for
brevity):
print "Please enter your password: ";
system("stty -echo");
chop($password=<STDIN>);
print "\n";
system("stty echo");
4.29) Is there any easy way to strip blank space from the
beginning/end of
a string?
Yes, there is. Using the substitution command, you can match the
blanks and replace it with nothing. For example, if you have the
string " String " you can use this:
$_ = " String ";
print ":$_:\n"; # OUTPUT: ": String :"
s/^\s*//;
print ":$_:\n"; # OUTPUT: ":String :"
s/\s*$//;
print ":$_:\n"; # OUTPUT: ":String:"
Unfortunately, there is no simple single statement that will strip
whitespace from both the front and the back in perl4. However, in
perl5 you should be able to say:
s/\s*(.*?)\s*$/$1/;
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 5/5 - External Program Interaction
úÿ(Continued from last message)
grep ($_ eq 'a', keys %ary) is FALSE
See, the whole entry is gone!
5.9) Why don't backticks work as they do in shells?
Several reason. One is because backticks do not interpolate
within
double quotes in Perl as they do in shells.
Let's look at two common mistakes:
$foo = "$bar is `wc $file`"; # WRONG
This should have been:
$foo = "$bar is " . `wc $file`;
But you'll have an extra newline you might not expect. This
does not work as expected:
$back = `pwd`; chdir($somewhere); chdir($back); # WRONG
Because backticks do not automatically eat trailing or embedded
newlines. The chop() function will remove the last character from
a string. This should have been:
chop($back = `pwd`); chdir($somewhere); chdir($back);
You should also be aware that while in the shells, embedding
single quotes will protect variables, in Perl, you'll need
to escape the dollar signs.
Shell: foo=`cmd 'safe $dollar'`
Perl: $foo=`cmd 'safe \$dollar'`;
5.10) How come my converted awk/sed/sh script runs more slowly in
Perl?
The natural way to program in those languages may not make for the
fastest
Perl code. Notably, the awk-to-perl translator produces sub-
optimal code;
see the a2p man page for tweaks you can make.
Two of Perl's strongest points are its associative arrays and its
regular
expressions. They can dramatically speed up your code when
applied
properly. Recasting your code to use them can help a lot.
How complex are your regexps? Deeply nested sub-expressions with
{n,m} or
* operators can take a very long time to compute. Don't use ()'s
unless
you really need them. Anchor your string to the front if you can.
Something like this:
next unless /^.*%.*$/;
runs more slowly than the equivalent:
next unless /%/;
Note that this:
next if /Mon/;
next if /Tue/;
next if /Wed/;
next if /Thu/;
next if /Fri/;
runs faster than this:
next if /Mon/ || /Tue/ || /Wed/ || /Thu/ || /Fri/;
which in turn runs faster than this:
next if /Mon|Tue|Wed|Thu|Fri/;
which runs *much* faster than:
next if /(Mon|Tue|Wed|Thu|Fri)/;
There's no need to use /^.*foo.*$/ when /foo/ will do.
Remember that a printf costs more than a simple print.
Don't split() every line if you don't have to.
Another thing to look at is your loops. Are you iterating through
indexed arrays rather than just putting everything into a hashed
array? For example,
@list = ('abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stv');
for $i ($[ .. $#list) {
if ($pattern eq $list[$i]) { $found++; }
}
First of all, it would be faster to use Perl's foreach mechanism
instead of using subscripts:
foreach $elt (@list) {
if ($pattern eq $elt) { $found++; }
}
Better yet, this could be sped up dramatically by placing the
whole
thing in an associative array like this:
%list = ('abc', 1, 'def', 1, 'ghi', 1, 'jkl', 1,
'mno', 1, 'pqr', 1, 'stv', 1 );
$found += $list{$pattern};
(but put the %list assignment outside of your input loop.)
You should also look at variables in regular expressions, which is
expensive. If the variable to be interpolated doesn't change over
the
life of the process, use the /o modifier to tell Perl to compile
the
regexp only once, like this:
for $i (1..100) {
if (/$foo/o) {
&some_func($i);
}
}
Finally, if you have a bunch of patterns in a list that you'd like
to
compare against, instead of doing this:
@pats = ('_get.*', 'bogus', '_read', '.*exit', '_write');
foreach $pat (@pats) {
if ( $name =~ /^$pat$/ ) {
&some_func();
last;
}
}
If you build your code and then eval it, it will be much faster.
For example:
@pats = ('_get.*', 'bogus', '_read', '.*exit', '_write');
$code = <<EOS
while (<>) {
study;
EOS
foreach $pat (@pats) {
$code .= <<EOS
if ( /^$pat\$/ ) {
&some_func();
next;
}
EOS
}
$code .= "}\n";
print $code if $debugging;
eval $code;
5.11) How can I call my system's unique C functions from Perl?
If these are system calls and you have the syscall() function,
then
you're probably in luck -- see the next question. If you're using
a
POSIX function, and are running perl5, you're also in luck: see
POSIX(3m). For arbitrary library functions, however, it's not
quite so
straight-forward. See "Where can I learn about linking C with
Perl?".
5.12) Where do I get the include files to do ioctl() or syscall()?
[h2ph]
[Note: as of perl5, you probably want to just use h2xs instead, at
least, if your system supports dynamic loading.]
These are generated from your system's C include files using the
h2ph
script (once called makelib) from the Perl source directory. This
will
make files containing subroutine definitions, like &SYS_getitimer,
which
you can use as arguments to your function.
You might also look at the h2pl subdirectory in the Perl source
for how to
convert these to forms like $SYS_getitimer; there are both
advantages and
disadvantages to this. Read the notes in that directory for
details.
In both cases, you may well have to fiddle with it to make these
work; it
depends how funny-looking your system's C include files happen to
be.
If you're trying to get at C structures, then you should take a
look
at using c2ph, which uses debugger "stab" entries generated by
your
BSD or GNU C compiler to produce machine-independent perl
definitions
for the data structures. This allows to you avoid hardcoding
structure layouts, types, padding, or sizes, greatly enhancing
portability. c2ph comes with the perl distribution. On an SCO
system, GCC only has COFF debugging support by default, so you'll
have
to build GCC 2.1 with DBX_DEBUGGING_INFO defined, and use -gstabs
to
get c2ph to work there.
See the file /pub/perl/info/ch2ph on convex.com via anon ftp
for more traps and tips on this process.
5.13) Why do setuid Perl scripts complain about kernel problems?
This message:
YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!
FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND
UNDUMP!
is triggered because setuid scripts are inherently insecure due to
a
kernel bug. If your system has fixed this bug, you can compile
Perl
so that it knows this. Otherwise, create a setuid C program that
just
execs Perl with the full name of the script. Here's what the
perldiag(1) man page says about this message:
YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!
(F) And you probably never will, since you probably don't have
the sources to your kernel, and your vendor probably doesn't
give a rip about what you want. Your best bet is to use the
wrapsuid script in the eg directory to put a setuid C
wrapper
around your script.
5.14) How do I open a pipe both to and from a command?
In general, this is a dangerous move because you can find yourself
in a
deadlock situation. It's better to put one end of the pipe to a
file.
For example:
# first write some_cmd's input into a_file, then
open(CMD, "some_cmd its_args < a_file |");
while (<CMD>) {
# or else the other way; run the cmd
open(CMD, "| some_cmd its_args > a_file");
while ($condition) {
print CMD "some output\n";
# other code deleted
}
close CMD || warn "cmd exited $?";
# now read the file
open(FILE,"a_file");
while (<FILE>) {
If you have ptys, you could arrange to run the command on a pty
and
avoid the deadlock problem. See the chat2.pl package in the
distributed library for ways to do this.
At the risk of deadlock, it is theoretically possible to use a
fork, two pipe calls, and an exec to manually set up the two-way
pipe. (BSD system may use socketpair() in place of the two pipes,
but this is not as portable.) The open2 library function
distributed
with the current perl release will do this for you.
It assumes it's going to talk to something like adb, both writing
to
it and reading from it. This is presumably safe because you
"know"
that commands like adb will read a line at a time and output a
line at
a time. Programs like sort that read their entire input stream
first,
however, are quite apt to cause deadlock.
There's also an open3.pl library that handles this for stderr as
well.
5.15) How can I capture STDERR from an external command?
There are three basic ways of running external commands:
system $cmd;
$output = `$cmd`;
open (PIPE, "cmd |");
In the first case, both STDOUT and STDERR will go the same place
as
the script's versions of these, unless redirected. You can always
put
them where you want them and then read them back when the system
returns. In the second and third cases, you are reading the
STDOUT
*only* of your command. If you would like to have merged STDOUT
and
STDERR, you can use shell file-descriptor redirection to dup
STDERR to
STDOUT:
$output = `$cmd 2>&1`;
open (PIPE, "cmd 2>&1 |");
Another possibility is to run STDERR into a file and read the file
later, as in
$output = `$cmd 2>some_file`;
open (PIPE, "cmd 2>some_file |");
Here's a way to read from both of them and know which descriptor
you got each line from. The trick is to pipe only STDERR through
sed, which then marks each of its lines, and then sends that
back into a merged STDOUT/STDERR stream, from which your Perl
program
then reads a line at a time:
open (CMD,
"cmd args | sed 's/^/STDOUT:/' |");
while (<CMD>) {
if (s/^STDOUT://) {
print "line from stdout: ", $_;
} else {
print "line from stdeff: ", $_;
}
}
Be apprised that you *must* use Bourne shell redirection syntax in
backticks, not csh! For details on how lucky you are that perl's
system() and backtick and pipe opens all use Bourne shell, fetch
the
file from convex.com called /pub/csh.whynot -- and you'll be glad
that
perl's shell interface is the Bourne shell.
There's an &open3 routine out there which was merged with &open2
in
perl5 production.
5.16) Why doesn't open return an error when a pipe open fails?
These statements:
open(TOPIPE, "|bogus_command") || die ...
open(FROMPIPE, "bogus_command|") || die ...
will not fail just for lack of the bogus_command. They'll only
fail if the fork to run them fails, which is seldom the problem.
If you're writing to the TOPIPE, you'll get a SIGPIPE if the child
exits prematurely or doesn't run. If you are reading from the
FROMPIPE, you need to check the close() to see what happened.
If you want an answer sooner than pipe buffering might otherwise
afford you, you can do something like this:
$kid = open (PIPE, "bogus_command |"); # XXX: check defined($kid)
(kill 0, $kid) || die "bogus_command failed";
This works fine if bogus_command doesn't have shell metas in it,
but
if it does, the shell may well not have exited before the kill 0.
You
could always introduce a delay:
$kid = open (PIPE, "bogus_command </dev/null |");
sleep 1;
(kill 0, $kid) || die "bogus_command failed";
but this is sometimes undesirable, and in any event does not
guarantee
correct behavior. But it seems slightly better than nothing.
Similar tricks can be played with writable pipes if you don't wish
to
catch the SIGPIPE.
5.17) Why can't my perl program read from STDIN after I gave it ^D
(EOF) ?
Because some stdio's set error and eof flags that need clearing.
Try keeping around the seekpointer and go there, like this:
$where = tell(LOG);
seek(LOG, $where, 0);
If that doesn't work, try seeking to a different part of the file
and
then back. If that doesn't work, try seeking to a different part
of
the file, reading something, and then seeking back. If that
doesn't
work, give up on your stdio package and use sysread. You can't
call
stdio's clearerr() from Perl, so if you get EINTR from a signal
handler, you're out of luck. Best to just use sysread() from the
start for the tty.
5.18) How can I translate tildes in a filename?
Perl doesn't expand tildes -- the shell (ok, some shells) do.
The classic request is to be able to do something like:
open(FILE, "~/dir1/file1");
open(FILE, "~tchrist/dir1/file1");
which doesn't work. (And you don't know it, because you
did a system call without an "|| die" clause! :-)
If you *know* you're on a system with the csh, and you *know*
that Larry hasn't internalized file globbing, then you could
get away with
$filename = <~tchrist/dir1/file1>;
but that's pretty iffy.
A better way is to do the translation yourself, as in:
$filename =~ s#^~(\w+)(/.*)?$#(getpwnam($1))[7].$2#e;
More robust and efficient versions that checked for error
conditions,
handed simple ~/blah notation, and cached lookups are all
reasonable
enhancements.
5.19) How can I convert my shell script to Perl?
Larry's standard answer is to send it through the shell to perl
filter,
otherwise known at tchrist@perl.com. Contrary to popular belief,
Tom
Christiansen isn't a real person. He is actually a highly
advanced
artificial intelligence experiment written by a graduate student
at the
University of Colorado. Some of the earlier tasks he was
programmed to
perform included:
* monitor comp.lang.perl and collect statistics on which questions
were asked with which frequency and to respond to them with stock
answers. Tom's programming has since outgrown this paltry task,
and it has been assigned to an undergraduate student from the
University of Florida. After all, we all know that student from
UF aren't able to do much more than documentation anyway. ;-)
* convert shell programs to perl programs
Actually, there is no automatic machine translator. Even if there
were, you wouldn't gain a lot, as most of the external programs
would
still get called. It's the same problem as blind translation into
C:
you're still apt to be bogged down by exec()s. You have to
analyze
the dataflow and algorithm and rethink it for optimal speedup.
It's
úÿ
not uncommon to see one, two, or even three orders of magnitude of
speed difference between the brute-force and the recoded
approaches.
5.20) Can I use Perl to run a telnet or ftp session?
Sure, you can connect directly to them using sockets, or you can
run a
session on a pty. In either case, Randal's chat2 package, which
is
distributed with the perl source, will come in handly. It address
much the same problem space as Don Libes's expect package does.
Two
examples of using managing an ftp session using chat2 can be found
on
convex.com in /pub/perl/scripts/ftp-chat2.shar .
Caveat lector: chat2 is documented only by example, may not run on
System V systems, and is subtly machine dependent both in its
ideas
of networking and in pseudottys.
Randal also has code showing an example socket session for
handling the
telnet protocol. You might nudge him for a copy.
Gene Spafford* has a nice ftp library package that will help with
ftp.
5.21) Why do I somestimes get an "Arguments too long" when I use <*>?
As of perl4.036, there is a certain amount of globbing that is
passed
out to the shell and not handled internally. The following code
(which
will, roughly, emulate "chmod 0644 *")
while (<*>) {
chmod 0644, $_;
}
is the equivalent of
open(FOO, "echo * | tr -s ' \t\r\f' '\\012\\012\\012\\012'|");
while (<FOO>) {
chop;
chmod 0644, $_;
}
Until globbing is built into Perl, you will need to use some form
of
non-globbing work around.
Something like the following will work:
opendir(DIR,'.');
chmod 0644, grep(/\.c$/, readdir(DIR));
closedir(DIR);
This example is taken directly from "Programming Perl" page 78.
If you've installed tcsh as /bin/csh, you'll never have this
problem.
5.22) How do I do a "tail -f" in Perl?
Larry says that the solution is to put a call to seek in yourself.
First try
seek(GWFILE, 0, 1);
If that doesn't work (depends on your stdio implementation), then
you need something more like this:
for (;;) {
for ($curpos = tell(GWFILE); $_ = <GWFILE>; $curpos = tell(GWFILE)) {
# search for some stuff and put it into files
}
sleep for a while
seek(GWFILE, $curpos, 0);
}
5.23) Is there a way to hide perl's command line from programs such as
"ps"?
Generally speaking, if you need to do this you're either using
poor
programming practices or are far too paranoid for your own good.
If you
need to do this to hide a password being entered on the command
line,
recode the program to read the password from a file or to prompt
for
it. (see question 4.24) Typing a password on the command line is
inherently insecure as anyone can look over your shoulder to see
it.
If you feel you really must overwrite the command line and hide
it, you
can assign to the variable "$0". For example:
#!/usr/local/bin/perl
$0 = "Hidden from prying eyes";
open(PS, "ps") || die "Can't PS: $!";
while (<PS>) {
next unless m/$$/;
}
It should be noted that some OSes, like Solaris 2.X, read directly
from
the kernel information, instead of from the program's stack, and
hence
don't allow you to change the command line.
Stephen P Potter spp@vx.com Varimetrix Corporation
2350 Commerce Park Drive, Suite 4 Palm Bay, FL 32905
(407) 676-3222 CAD/CAM/CAE/Software
ÿ@SUBJECT:comp.lang.perl FAQ 5/5 - External Program Interaction
Message-ID: <perl-faq/part5_786188328@rtfm.mit.edu>
Path:
ns.channel1.com!wizard.pn.com!Germany.EU.net!howland.reston.ans.net
spool.mu.edu!bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
From: spp@vx.com
Newsgroups: comp.lang.perl,comp.answers,news.answers
Subject: comp.lang.perl FAQ 5/5 - External Program Interaction
Supersedes: <perl-faq/part5_784894001@rtfm.mit.edu>
Followup-To: poster
Date: 30 Nov 1994 09:40:48 GMT
Organization: none
Lines: 883
Approved: news-answers-request@MIT.EDU
Distribution: world
Message-ID: <perl-faq/part5_786188328@rtfm.mit.edu>
References: <perl-faq/part0_786188328@rtfm.mit.edu>
NNTP-Posting-Host: bloom-picayune.mit.edu
X-Last-Updated: 1994/11/14
Originator: faqserv@bloom-picayune.MIT.EDU
Xref: ns.channel1.com comp.lang.perl:39240 comp.answers:8357
news.answers:32284
Archive-name: perl-faq/part5
Version: $Id: part5,v 2.2 1994/11/07 18:06:59 spp Exp spp $
Posting-Frequency: bi-weekly
This posting contains answers to the following questions about Array,
Shell
and External Program Interactions with Perl:
5.1) What is the difference between $array[1] and @array[1]?
Always make sure to use a $ for single values and @ for multiple
ones.
Thus element 2 of the @foo array is accessed as $foo[2], not
@foo[2],
which is a list of length one (not a scalar), and is a fairly
common
novice mistake. Sometimes you can get by with @foo[2], but it's
not really doing what you think it's doing for the reason you
think
it's doing it, which means one of these days, you'll shoot
yourself
in the foot; ponder for a moment what these will really do:
@foo[0] = `cmd args`;
@foo[2] = <FILE>;
Just always say $foo[2] and you'll be happier.
This may seem confusing, but try to think of it this way: you use
the
character of the type which you *want back*. You could use
@foo[1..3] for
a slice of three elements of @foo, or even @foo{A,B,C} for a slice
of
of %foo. This is the same as using ($foo[1], $foo[2], $foo[3])
and
($foo{A}, $foo{B}, $foo{C}) respectively. In fact, you can even
use
lists to subscript arrays and pull out more lists, like @foo[@bar]
or
@foo{@bar}, where @bar is in both cases presumably a list of
subscripts.
5.2) How can I make an array of arrays or other recursive data types?
In Perl5, it's quite easy to declare these things. For example
@A = (
[ 'ww' .. 'xx' ],
[ 'xx' .. 'yy' ],
[ 'yy' .. 'zz' ],
[ 'zz' .. 'zzz' ],
);
And now reference $A[2]->[0] to pull out "yy". These may also
nest
and mix with tables:
%T = (
key0, { k0, v0, k1, v1 },
key1, { k2, v2, k3, v3 },
key2, { k2, v2, k3, [ 0, 'a' .. 'z' ] },
);
Allowing you to reference $T{key2}->{k3}->[3] to pull out 'c'.
Perl4 is infinitely more difficult. Remember that Perl[0..4]
isn't
about nested data structures. It's about flat ones, so if you're
trying to do this, you may be going about it the wrong way or
using the
wrong tools. You might try parallel arrays with common
subscripts.
But if you're bound and determined, you can use the multi-
dimensional
array emulation of $a{'x','y','z'}, or you can make an array of
names
of arrays and eval it.
For example, if @name contains a list of names of arrays, you can
get
at a the j-th element of the i-th array like so:
$ary = $name[$i];
$val = eval "\$$ary[$j]";
or in one line
$val = eval "\$$name[$i][\$j]";
You could also use the type-globbing syntax to make an array of
*name
values, which will be more efficient than eval. Here @name hold a
list
of pointers, which we'll have to dereference through a temporary
variable.
For example:
{ local(*ary) = $name[$i]; $val = $ary[$j]; }
In fact, you can use this method to make arbitrarily nested data
structures. You really have to want to do this kind of thing
badly to
go this far, however, as it is notationally cumbersome.
Let's assume you just simply *have* to have an array of arrays of
arrays. What you do is make an array of pointers to arrays of
pointers, where pointers are *name values described above. You
initialize the outermost array normally, and then you build up
your
pointers from there. For example:
@w = ( 'ww' .. 'xx' );
@x = ( 'xx' .. 'yy' );
@y = ( 'yy' .. 'zz' );
@z = ( 'zz' .. 'zzz' );
@ww = reverse @w;
@xx = reverse @x;
@yy = reverse @y;
@zz = reverse @z;
Now make a couple of arrays of pointers to these:
@A = ( *w, *x, *y, *z );
@B = ( *ww, *xx, *yy, *zz );
And finally make an array of pointers to these arrays:
@AAA = ( *A, *B );
To access an element, such as AAA[i][j][k], you must do this:
local(*foo) = $AAA[$i];
local(*bar) = $foo[$j];
$answer = $bar[$k];
Similar manipulations on associative arrays are also feasible.
You could take a look at recurse.pl package posted by Felix Lee*,
which
lets you simulate vectors and tables (lists and associative
arrays) by
using type glob references and some pretty serious wizardry.
In C, you're used to creating recursive datatypes for operations
like
recursive decent parsing or tree traversal. In Perl, these
algorithms
are best implemented using associative arrays. Take an array
called
%parent, and build up pointers such that $parent{$person} is the
name
of that person's parent. Make sure you remember that
$parent{'adam'}
is 'adam'. :-) With a little care, this approach can be used to
implement general graph traversal algorithms as well.
5.3) How do I make an array of structures containing various data
types?
The best way to do this is to use an associative array to model
your
structure, then either a regular array (AKA list) or another
associative array (AKA hash, table, or hash table) to store it.
%foo = (
'field1' => "value1",
'field2' => "value2",
'field3' => "value3",
...
);
...
@all = ( \%foo, \%bar, ... );
print $all[0]{'field1'};
Or even
@all = (
{
'field1' => "value1",
'field2' => "value2",
'field3' => "value3",
...
},
{
'field1' => "value1",
'field2' => "value2",
'field3' => "value3",
...
},
...
)
See perlref(1).
5.4) How can I extract just the unique elements of an array?
There are several possible ways, depending on whether the
array is ordered and you wish to preserve the ordering.
a) If @in is sorted, and you want @out to be sorted:
$prev = 'nonesuch';
@out = grep($_ ne $prev && (($prev) = $_), @in);
This is nice in that it doesn't use much extra memory,
simulating uniq's behavior of removing only adjacent
duplicates.
b) If you don't know whether @in is sorted:
undef %saw;
@out = grep(!$saw{$_}++, @in);
c) Like (b), but @in contains only small integers:
@out = grep(!$saw[$_]++, @in);
d) A way to do (b) without any loops or greps:
undef %saw;
@saw{@in} = ();
@out = sort keys %saw; # remove sort if undesired
e) Like (d), but @in contains only small positive integers:
undef @ary;
@ary[@in] = @in;
@out = sort @ary;
5.5) How can I tell whether an array contains a certain element?
There are several ways to approach this. If you are going to make
this query many times and the values are arbitrary strings, the
fastest way is probably to invert the original array and keep an
associative array lying about whose keys are the first array's
values.
@blues = ('turquoise', 'teal', 'lapis lazuli');
undef %is_blue;
for (@blues) { $is_blue{$_} = 1; }
Now you can check whether $is_blue{$some_color}. It might have
been
a good idea to keep the blues all in an assoc array in the first
place.
If the values are all small integers, you could use a simple
indexed array. This kind of an array will take up less space:
@primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
undef @is_tiny_prime;
for (@primes) { $is_tiny_prime[$_] = 1; }
Now you check whether $is_tiny_prime[$some_number].
If the values in question are integers instead of strings, you can
save
quite a lot of space by using bit strings instead:
@articles = ( 1..10, 150..2000, 2017 );
undef $read;
grep (vec($read,$_,1) = 1, @articles);
Now check whether vec($read,$n,1) is true for some $n.
5.6) How do I sort an associative array by value instead of by key?
You have to declare a sort subroutine to do this, or use an inline
function. Let's assume you want an ASCII sort on the values of
the
associative array %ary. You could do so this way:
foreach $key (sort by_value keys %ary) {
print $key, '=', $ary{$key}, "\n";
}
sub by_value { $ary{$a} cmp $ary{$b}; }
If you wanted a descending numeric sort, you could do this:
sub by_value { $ary{$b} <=> $ary{$a}; }
You can also inline your sort function, like this, at least if
you have a relatively recent patchlevel of perl4 or are running
perl5:
foreach $key ( sort { $ary{$b} <=> $ary{$a} } keys %ary ) {
print $key, '=', $ary{$key}, "\n";
}
If you wanted a function that didn't have the array name hard-
wired
into it, you could so this:
foreach $key (&sort_by_value(*ary)) {
print $key, '=', $ary{$key}, "\n";
}
sub sort_by_value {
local(*x) = @_;
sub _by_value { $x{$a} cmp $x{$b}; }
sort _by_value keys %x;
}
If you want neither an alphabetic nor a numeric sort, then you'll
have to code in your own logic instead of relying on the built-in
signed comparison operators "cmp" and "<=>".
Note that if you're sorting on just a part of the value, such as a
piece you might extract via split, unpack, pattern-matching, or
substr, then rather than performing that operation inside your
sort
routine on each call to it, it is significantly more efficient to
build a parallel array of just those portions you're sorting on,
sort
the indices of this parallel array, and then to subscript your
original
array using the newly sorted indices. This method works on both
regular and associative arrays, since both @ary[@idx] and
@ary{@idx}
make sense. See page 245 in the Camel Book on "Sorting an Array
by a
Computable Field" for a simple example of this.
5.7) How can I know how many entries are in an associative array?
While the number of elements in a @foobar array is simply @foobar
when
used in a scalar, you can't figure out how many elements are in an
associative array in an analogous fashion. That's because %foobar
in
a scalar context returns the ratio (as a string) of number of
buckets
filled versus the number allocated. For example, scalar(%ENV)
might
return "20/32". While perl could in theory keep a count, this
would
break down on associative arrays that have been bound to dbm
files.
However, while you can't get a count this way, one thing you *can*
use
it for is to determine whether there are any elements whatsoever
in
the array, since "if (%table)" is guaranteed to be false if
nothing
has ever been stored in it.
As of perl4.035, you can says
$count = keys %ARRAY;
keys() when used in a scalar context will return the number of
keys,
rather than the keys themselves.
5.8) What's the difference between "delete" and "undef" with %arrays?
Pictures help... here's the %ary table:
keys values
+------+------+
| a | 3 |
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
And these conditions hold
$ary{'a'} is true
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is true
exists $ary{'a'} is true (perl5 only)
grep ($_ eq 'a', keys %ary) is true
If you now say
undef $ary{'a'}
your table now reads:
keys values
+------+------+
| a | undef|
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
and these conditions now hold; changes in caps:
$ary{'a'} is FALSE
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is FALSE
exists $ary{'a'} is true (perl5 only)
grep ($_ eq 'a', keys %ary) is true
Notice the last two: you have an undef value, but a defined key!
Now, consider this:
delete $ary{'a'}
your table now reads:
keys values
+------+------+
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
and these conditions now hold; changes in caps:
$ary{'a'} is false
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is false
exists $ary{'a'} is FALSE (perl5 only)
Comments
Post a Comment