#!/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%
Tre typer datastrukture: Skalare, lister og hash-lister
$tal = 42; $tal2 = "42"; $str = "foobaz";
@liste = (17, 42, 666); $liste[0] = 18;
%hash = ( random => 17,
answer => 42,
);
$hash{beast} = 666;
$_ 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;
if ($n == 42) {
print "42!";
} else {
print "øv!";
}
unless ($n == 42) {
print "Bzeeet, prøv igen";
}
Perl har en særlig opfattelse af hvad der er sandt og falsk på grund af konverteringen mellem strenge og tal.
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") {
[....]
}
while ($n < 10) {
$n = $n + 1;
}
for($n = 0; $n < 10; $n++) {
print $n;
}
for $n (@liste) {
print $n;
}
Modifiers er basalt set kontrolstrukture sat bag på en almindelig komando
print "Debugbesked" if ($debug); print $_ for (@liste);
sub fac{
my ($n) = @_;
if ($n == 0) {
return 1;
}
$n * fac($n - 1);
}
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.
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 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.
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 tager en liste og udfører en operation på hvert element i listen:
@added_one = map { $_ + 1 } @numbers;
grep tager en liste og returnerer en liste med nogle af elementerne i den oprindelige liste:
@even = grep { ($_ % 2) == 0 } @numbers;
Regulære udtryk er hoveddrivkraften i Perls evner til tekstmanipulation. Det er meget kraftigt og giver mulighed for meget kompakt og ulæselig kode.
Hvis S og T er regulære udtryk kan man sætte dem sammen på forskellige måder:
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).
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!.
/usr/bin/perl har en række flag der understøtter one-liners:
while (<>) {
[....]
}
while (<>) {
[....]
} continue {
print $_;
}
while(<>) {
@F = split(' ', @_);
[....]
}
Manualsiderne kommer godt i dybden med perl. Man kan starte med perlintro(1), perldata(1) og perlsyn(1).