Perl is now a family of languages. All languages in the family except Perl 5 and Raku are obsolete.
The Perl language are very popular, “particularly well-suited for tasks involving quick prototyping, system utilities, software tools, system management tasks, database access, graphical programming, networking, and world wide web programming... [though] probably not well-suited for real-time embedded systems, low-level operating systems development work like device drivers or context-switching code, complex multi-threaded shared-memory applications, or extremely large applications.” (from the Perl FAQ).
The Perl home page is at perl.org.
Perl was born in the 1980s but is still going! Here are a few of the versions and their release dates:
1 1987-12-18 2 1988-06-05 3 1989-10-18 4 1991-03-21 5.000 1994-10-17 5.005 1998-07-22 5.6 2000-03-28 5.8 2002-07-18 5.10 2007-12-18 5.12 2010-04-12 5.14 2011-05-14 . . . 5.32 2020-06-20 5.34 2021-05-20
See the complete Perl history at perlhist.
# The classic hello world script. print "Hello, World\n";
To compile and run this, just enter
perl hello.pl
On a Unix system, you can simply rename the file hello
(instead
of hello.pl
), add a shebang comment with the pathname of your
perl interpreter, and give the file executable permission.
Here is a cute little one with for loops:
# A script to print some Pythagorean triples. for $c (1..100) { for $b (1..$c) { for $a (1..$b) { if ($a * $a + $b * $b == $c * $c) { printf "%4i%4i%4i\n", $a, $b, $c; } } } }
and a Fibonacci numnber script that illustrates command line arguments
# A script to write the Fibonacci numbers up to and including the # first commandline argument. my $n = shift; my ($a, $b) = (0, 1); while ($b < $n) { print "$b "; ($a, $b) = ($b, $a + $b); }
and one that illustrates subroutines
# A simple script that displays the mean and median # of an array of values, passed in on the command line. use strict; use warnings; sub median { my @a = sort {$a <=> $b} @_; my $length = scalar @a; return undef unless $length; ($length % 2) ? $a[$length/2] : ($a[$length/2] + $a[$length/2-1]) / 2.0; } sub sum { my $total = 0; $total += $_ for (@_); $total; } sub mean { @_ ? sum(@_) / (scalar @_) : undef; } print "input array is: @ARGV\n"; print "sum is: " . sum(@ARGV) . "\n"; print "mean is: " . mean(@ARGV) . "\n"; print "median is: " . median(@ARGV) . "\n"; print "input array is: @ARGV (just making sure it did not change)\n";
This script attempts to walk you through some very basic elements of the language. For a better "tutorial" see perlintro.
# Examples of declaring variables and subroutines, and using some # of the built-in functions. use strict; use warnings; # Perl scripts don't need special main functions, subroutines, # or main classes; just start writing code. End each statement # with a semicolon. print "Hello\n"; # Variables can be scalars, arrays or hashes. You don't specify type # names like int or string when you declare them. my $x = 7; my $y = $x * 2; my @animals = ('cow', 'pig', 'horse', 'beetle', 'whale'); my %numbers = ('odin' => 1, 'dva' => 2, 'tri' => 3); # Perl has assignment statements. $x = 35; $x = $x * 4; $x = "Another string"; $x = 75.2E4; $x = 99; # There are some built-in variables with really funny names $, = "|"; # Strings can be in single or double quotes, but only double # quotes interpolate escape characters and variables. print 'The answer is $x \n'; print "The answer is $x \n"; print "$x cubed is " . $x ** 3 . "\n"; # Index arrays with [], get the index of the last element with #, and # and get the length of the array by using it in a "scalar context". my @stuff = (4.5, "cat", 2, 'dog', 'bear', 100); print $stuff[0], $stuff[1], $#stuff, "\n"; $x = @stuff; print "$x\n"; print "Six\n" if @stuff == 6; print "@stuff\n"; print "@stuff[1, 4, 5]\n"; print "@stuff[2..4]\n"; # Using hashes print $numbers{'dva'}, "\n"; $numbers{'chityri'} = 4; print %numbers, "\n"; print "%numbers\n"; # Tired of writing the "\n" all the time? How about writing a subroutine? # Within the subroutine's body, all the parameters have been collected # into the @_ variable. sub println { local $, = '|'; print @_; print "\n"; } # Some built-in array functions my @numbers = (2,3,4,5); push @numbers, 6, 7, 8; println @numbers; pop @numbers; println @numbers; unshift @numbers, 0, 1; println @numbers; shift @numbers; shift @numbers; $x = shift @numbers; println "$x was shifted off of @numbers";
There are few kinds of types:
You can only make variables of the first three types.
Names for scalars start with $
, arrays with @
, hashes with %
, subroutines with &
, and typeglobs with *
. The others just start with letters so don’t get them confused with keywords.
You cannot make arrays of arrays, or arrays of hashes, or arrays of arrays and hashes, or hashes of arrays, or hashes of hashes, or hashes of arrays and hashes. But you can put references in arrays and hashes because references are scalars, so you can get whatever data structure you really want.
A declaration can go anywhere a statement can go. Declarations can be scoped with my
, our
, or local
.
use strict; use warnings; our $x = 1; our $y = 101; our $z = 201; sub g { print "Entering g\n"; print "In g, x = $x and y = $y and z = $z\n"; print "Leaving g\n"; } sub f { print "Entering f\n"; my $x = 2; local $y = 102; $z = 202; print "In f, assigned my x = $x and local y = $y and z = $z\n"; g(); print "Leaving f\n"; } print "Initially globals x = $x and y = $y and z = $z\n"; f(); print "Finally globals x = $x and y = $y and z = $z\n";
A Perl statement is either an expression (possibly with a modifier) or an if
, unless
, while
, until
, or for
statement.
SIMPLE_STATEMENT → EXPR MODIFIER? MODIFIER → if EXPR | unless EXPR | while EXPR | until EXPR | (for|foreach) LIST COMPOUND_STATEMENT → if '(' EXPR ')' BLOCK (elsif '(' EXPR ')' BLOCK)* (else BLOCK)? | unless '(' EXPR ')' BLOCK (elsif '(' EXPR ')' BLOCK)* (else BLOCK)? | LABEL? while '(' EXPR ')' BLOCK (continue BLOCK)? | LABEL? until '(' EXPR ')' BLOCK (continue BLOCK)? | LABEL? (for|foreach) '(' EXPR ';' EXPR ';' EXPR ')' BLOCK | LABEL? (for|foreach) VAR? '(' LIST ')' (continue BLOCK)?
Here are the Perl operators, presented from highest to lowest precedence.
Operator(s) | Associativity | Comments |
---|---|---|
Terms | No | Variables, quote and quote-like operators, parenthesized expressions, subroutine or operator call with parenthesized args, [] constructor, {} constructor, do{}, eval{}, sub{} |
-> | Left | Infix dereference |
++ -- | No | Increment, decrement |
** | Right | Exponentiation |
! ~ \ + - | Right | Unary prefix operators: logical not, bitwise complement, reference creator, unary plus, unary negation |
=~ !~ | Left | Binding (binds a string to a pattern match, substitution, or transliteration). |
* / % x | Left | multiply, divide, modulo, string repetition |
+ - . | Left | numeric add, numeric subtract, string concatenation |
<< >> | Left | bitwise shifts |
Named unary operators | Right | There are around 75 of these, including the 27 filetest operators. Examples: chdir, exists, length, scalar, sin, sqrt. Make your own by using the ($) prototype. |
< <= > >= lt gt le ge | No | less-than, less-than-or-equal, greater-than, greater-than-or-equal |
== != <=> eq, ne, cmp | No | equal-to, not-equal-to, compare |
& | Left | bitwise-and |
| ^ | Left | bitwise-or, bitwise-xor |
&& | Left | logical-short-circuit-and |
|| | Left | logical-short-circuit-or |
.. ... | No | Range operators |
?: | Right | conditional |
= **= += -= .= *= /= %= x= &= |= ^= <<= >>= &&= ||= | Right | assignment |
, => | Left | comma |
List operators | Right | Basically, these are the functions that aren’t explicitly named unary operators. |
not | Right | Logical negation |
and | Left | logical-short-circuit-and |
or xor | Left | logical-short-circuit-or, logical xor |
Perl has a couple hundred functions (you can call them operators, too) that aren’t part of any package. They are:
Scalars | chomp, chop, chr, crypt, hex, index, lc, lcfirst, length, oct, ord, pack, q/STRING/, qq/STRING/, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y///
|
Regexs/pattern matching | m//, pos, quotemeta, s///, split, study, qr//
|
Numerics | abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand
|
For real @ARRAYs | pop, push, shift, splice, unshift
|
For list data | grep, join, map, qw/STRING/, reverse, sort, unpack
|
%HASHes | delete, each, exists, keys, values
|
Input and output | binmode, close, closedir, dbmclose, dbmopen, die, eof, fileno, flock, format, getc, print, printf, read, readdir, rewinddir, seek, seekdir, select, syscall, sysread, sysseek, syswrite, tell, telldir, truncate, warn, write
|
Fixed length data | pack, read, syscall, sysread, syswrite, unpack, vec
|
Filehandles, files, directories | -X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, stat, symlink, sysopen, umask, unlink, utime
|
Control flow | caller, continue, die, do, dump, eval, exit, goto, last, next, redo, return, sub, wantarray
|
Scoping | caller, import, local, my, our, package, use
|
Miscellaneous | defined, dump, eval, formline, local, my, our, reset, scalar, undef, wantarray
|
Processeses and process groups | alarm, exec, fork, getpgrp, getppid, getpriority, kill, pipe, qx/STRING/, setpgrp, setpriority, sleep, system, times, wait, waitpid
|
Modules | do, import, no, package, require, use
|
Classes and OOP | bless, dbmclose, dbmopen, package, ref, tie, tied, untie, use
|
Sockets | accept, bind, connect, getpeername, getsockname, getsockopt, listen, recv, send, setsockopt, shutdown, socket, socketpair
|
System V IPC | msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop, shmctl, shmget, shmread, shmwrite
|
User and group | endgrent, endhostent, endnetent, endpwent, getgrent, getgrgid, getgrnam, getlogin, getpwent, getpwnam, getpwuid, setgrent, setpwent
|
Networking | endprotoent, endservent, gethostbyaddr, gethostbyname, gethostent, getnetbyaddr, getnetbyname, getnetent, getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, sethostent, setnetent, setprotoent, setservent
|
Time | gmtime, localtime, time, times
|
Note: If you’re the type that doesn’t use a lot of parentheses, then you need to remember which of these are list operators and which of these are true unary operators! Good luck!
See http://perldoc.perl.org/perlvar.html for the complete list.
Perl has pacakges for namespace control, and some nice syntax to make object oriented programming look pleasant.
$x = 1; package A; $x = 2; package B; $x = 3; print "$x\n"; print "$A::x\n"; print "$B::x\n"; print "$main::x\n"; print "$C::x\n"; package A; $x = 7; $B::y = 12; sub f {print "The f in A\n";} sub g {print "(", scalar(@_), " args) ", "@_\n";} package B; print "$y\n"; A::f(); package main; print "$x\n"; A::g(); A::g(100); A::g(1, 2, 3); A->g(); A->g(100); A->g(1, 2, 3); package C; A->g(100); package A; $y = {name=>"alice", age=>21}; print "$y\n"; print "%$y\n"; bless $y, "A"; print "$y\n"; print "%$y\n"; %x = %$y; print "$x{name}\n"; g($y); $y->g(); $y->g(400); g(); package B; print "%$A::y\n"; $A::y->g(100); A->g(100); g A(100); g A; A->g;
Modules allow for separate compilation. Keep the package names in sync with the file names and it all works out.
# Trig.pm # # Just illustrates how to write a simple module. Note this # doesn't "export" anything, so all users have to qualify # names. use warnings; package Trig; $pi = atan2(1,1) * 4; sub tan { sin($_[0]) / cos($_[0]); } sub circle_area { my $radius = shift; return $pi * $radius * $radius; } 1;
To use...
# This little script calculates frustum parameters given # a vertical field of view and an aspect ratio. The only # reason I wrote this is to show how to use a user-defined # module. use Trig; print "Did you know pi was about $Trig::pi?\n"; # Given: fovy, depth, aspect. # Returns width, height. sub frustum { my ($fovy, $depth, $aspect) = @_; my $height = (2 * $depth) * Trig::tan($fovy / 2); my $width = $aspect * $height; return ($width, $height); } $, = ","; print frustum($Trig::pi/2, 10, 2); print "\n";
More fun stuff with modules: BEGIN, END, AUTOLOAD. Privacy? Well you can’t stop other people from inserting names into your package’s namespace, but you can use "my" to "hide" variables and subroutine references.
The "standard" ones are listed at http://perldoc.perl.org/perlmodlib.html but there are many others that have been contributed; see http://www.perl.com/CPAN/modules/00modlist.long.html.
Perl’s OOP is based on the idea that
This example barely scratches the surface of what you can, and should, do:
# Very small, but classic, OOP demo. use strict; use warnings; # # Abstract base class. Create animals of any subclass by calling # new with the animal's name. There is a speak method which delgates # to the subclass-supplied sound subroutine. # package Animal; sub new { my ($class, $name) = @_; # first parameter is class name my $animal = {name => $name}; # representation is a hash bless $animal, $class; # "tags" (blesses) the hash return $animal; # constructors return object refs } sub speak { my $self = shift; print $self->{name}, " says ", $self->sound(), "\n"; } # # Subclasses. # package Cow; @Cow::ISA = qw(Animal); sub sound { "moooo" } package Horse; @Horse::ISA = qw(Animal); sub sound { "neigh" } package Sheep; @Sheep::ISA = qw(Animal); sub sound { "baaaaa" } # # Illustration of use, showing the variety of styles one can # use make an animal and tell it to speak. # package main; my $s = Horse->new("CJ"); # The usual way to call "constructor" $s->speak; # dispatches perfectly - see why? my $c = new Cow "Bessie"; # Funny syntax to make C++ folks happy $c->speak(); my $h = new Sheep("Little Lamb"); # In case you love parens Animal::speak($h); # Works, but verbose and uncommon
Tutorials and references at perl.org: Beginner’s OO Tutorial, Tom’s OO Tutorial, Tom’s OO Tutorial for Class Data, and Reference page on Perl objects.
These notes are in no way meant to be complete. We barely got started! Here are a few things not covered in these notes:
printf
and sprintf