Hvad er Perl?


Filosofien bag perl


Et eksempel

#!/usr/bin/perl

sub fac{
    my ($n) = @_;
    
    if ($n == 0) {
        return 1;
    } else {
        return $n * fac($n - 1);
    }
}

for $i (1 .. 10) {
    print "$i! = ", fac($i), "\n";
}
__END__

Nå dette køres ser man følgende:

plugh% perl test.pl 
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
plugh% 

Datastrukture i Perl

Tre typer datastrukture: Skalare, lister og hash-lister

Skalarer

$tal  = 42;
$tal2 = "42";
$str  = "foobaz";

Lister

@liste = (17, 42, 666);
$liste[0] = 18;

Hash-lister

%hash = ( random => 17,
          answer => 42,
        );
$hash{beast} = 666;

Specielle variable

$_ og @_ bliver ofte brugt som standardvariable. En række konstruktioner sætter disse variable og en række funktioner arbejder på disse, hvis de ikke får eksplicitte argumenter

For eksempel gør følgende to linjer det præcis samme:

@liste = split "|", $_;
@liste = split "|";

Og disse:

$skalar = shift @_;
$skalar = shift;

Kontrolstrukture

Betingelser

if ($n == 42) {
    print "42!";
} else {
    print "øv!";
}

unless ($n == 42) {
    print "Bzeeet, prøv igen";
}

Sandhedsværdier og sammenligninger

Perl har en særlig opfattelse af hvad der er sandt og falsk på grund af konverteringen mellem strenge og tal.

  1. Enhver streng er sand undtagen "" og "0"
  2. Ethver talværdi er sand undtagen 0
  3. Den udefinerede værdi er falsk
  4. Enhver reference er sand

En ofte set fejl er når folk prøver at sammenligne værdier. Hvis man prøver at sammenligne strenge med == eller ligende. Brug eq og ne istedet.

Altså:

if ($streng eq "test") {
    [....]
}

og ikke

if ($streng == "test") {
    [....]
}

Løkker

while ($n < 10) {
    $n = $n + 1;
}

for($n = 0; $n < 10; $n++) {
    print $n;
}

for $n (@liste) {
    print $n;
}

Kontrol af løkkestrukture

next
Næste gennemgang af løkken
last
Afslut løkken
redo
Gentag denne gennemgang af løkken

Modifiers

Modifiers er basalt set kontrolstrukture sat bag på en almindelig komando

print "Debugbesked" if ($debug);
print $_ for (@liste);

Funktioner

sub fac{
    my ($n) = @_;
    
    if ($n == 0) {
        return 1;
    }
    $n * fac($n - 1);
}

Filhåndtering

Skrive til filer

open(FH, '>', '/tmp/file');
print FH "Tekstlinje\n";
close FH;


læse fra filer:

open(FH, '<', '/tmp/file');
while(<FH>) {
    print $_;
}
close FH;


Der findes tre standard-filehandles: STDIN, STDOUT og STDERR.


Moduler

Der findes en masse moduler til perl. De bruges således

use IO::File;
use POSIX qw(isatty);
use CGI qw(:html4 :form);
Moduler implementerer enten en klasse (objekt orienteret) eller eksporterer bare en række funktioner.

Objekter

Objekter er noget påklistret og er primært bare syntaktisk sukker. En klasse er bare et almindeligt perl-modul der implementerer noget funktionalitet på en bestemt måde.

Man initialiserer et objekt af klassen/fra modulet Net::NNTP på følgende måde

$nntp = new Net::NNTP "news.sslug.dk";

Så kan man kalde metoder via $nntp:

@artikler = $nntp->group("sslug.misc");
if ($nntp->postok) {
    [....]
}
$nntp->quit;

Da perl er type-løst forgår det hele på køretidspunktet.


Andre specialiteter

Der er et par andre ting som man ikke normalt støder på i C, C++, Jave etc, men som fortjener at bliver nævnt:

map

map tager en liste og udfører en operation på hvert element i listen:

@added_one = map { $_ + 1 } @numbers;

grep

grep tager en liste og returnerer en liste med nogle af elementerne i den oprindelige liste:

@even = grep { ($_ % 2) == 0 } @numbers;

Regulære udtryk

Regulære udtryk er hoveddrivkraften i Perls evner til tekstmanipulation. Det er meget kraftigt og giver mulighed for meget kompakt og ulæselig kode.

Simple matches

a, b, c, ...
Bogstaver og mange andre tegn matcher sig selv
.
Punktum matcher alt
\n, \t, \033, \x1B
Specielle enkelttegn, ascii-tegn skrevet som octal og hex
\w, \W
Tegn der kan indgå i ord og ikke indgå i ord
\s, \S
blanktegn og ikke-blanktegn
\d, \D
Tal
^ og $
Henholdsvis begyndelse og slutningen af linjen

Tegnklasser

[aeiouy], [a-z], [A-Za-z]
Et af tegn i klassen
[[:alpha:]], [[:alnum:]], ...
POSIX-tegnklasser. Afhængig af locale-opsætningen
[[:alpha:]0-3@]
Blanding af ovenstående

Sammensatte regulære udtryk

Hvis S og T er regulære udtryk kan man sætte dem sammen på forskellige måder:

S{2}
Matcher 2 gange af S
S{2,5}
Matcher mellem 2 og 5 gange af S
S?, S* og S+
Det samme som S{0,1}, S{0,STORT TAL}, S{1,STORT TAL}
S|T
Matcher S eller T
ST
S efterfulgt af T

Alle matches er grådig. Altså de matcher så meget som overhovedet muligt. Sætter man et spørgsmålstegn efter et match prøver den at matche så lidt som muligt.

Der findes en række mere advancerede muligheder, men man kommer langt med ovenstående. Læs perlre(1).

Grupperinger og gemte matches

(S)
Grupperer og gemme den streng som matches af S
(?:S)
Grupperer uden at gemme

Brug af regulære udtryk

Der er to måder at bruge regulære udtryk på: Matches og substitutioner.

$foobar = 'foobar';
if ($foobar =~ m/f(o*)b(\w*)/) {
    print "$1 $2"
}

Vil udskrive 'oo ar'.

$foobar = 'foobar';
$foobar =~ s/(o+)/z$1z$1z/;
print $foobar;

Vil udskrive 'fzoozoozbar'.

Man kan bruge alle mulige tegn i stedet for /'er. For eksempel er det nyttigt at kunne skrive m!/usr/bin!.


One-liners

/usr/bin/perl har en række flag der understøtter one-liners:

-e
Angive et 'script' på komandolinjen
-n
Indlejre koden i:
while (<>) {
    [....]
}
-p
Indlejre koden i:
while (<>) {
    [....]
} continue {
    print $_;
}
-a
Autosplitmode. Med -n og -p indsættes:
while(<>) {
    @F = split(' ', @_);
    [....]
}
-F
Giver et pattern til autosplit

Gode bøger, referencer og ligende

Learning Perl
Introduktion til Perl. Velegnet hvis man ikke kan programmerer i forvejen.
Programming Perl
God lærebog i perl. Velegnet hvis man kan programmerer i forvejen eller vil vidre fra Learning Perl.
Advanced Perl Programming
En god bog om mere advancerede emner. Inkluderer et afsnit om perl internals.

Manualsiderne kommer godt i dybden med perl. Man kan starte med perlintro(1), perldata(1) og perlsyn(1).

http://learn.perl.org/