1977 lines
56 KiB
HTML
1977 lines
56 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
|
|
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
|
<HTML>
|
|
|
|
<HEAD>
|
|
<LINK REL="StyleSheet" HREF="perlkurs.css" TYPE="text/css" MEDIA="screen">
|
|
<TITLE>Perlkurset, Høst'99</TITLE>
|
|
|
|
<META NAME='version' CONTENT='1.96'>
|
|
|
|
<META NAME='author' CONTENT='Salve J. Nilsen'>
|
|
|
|
</HEAD><BODY BGCOLOR=white>
|
|
<P><H1><FONT SIZE=+4>Perlkurset, Høsten '99</FONT></H1>I regi av Programvareverkstedets Faglige Forum</P>
|
|
<HR><P><TABLE WIDTH=100%>
|
|
<TR><TD WIDTH=80%><H2>Kursoversikt</H2>
|
|
Kurset er beregnet for de som er kjent med grunnleggende
|
|
programmering inkludert funksjoner, bibliotek og elementære
|
|
objekt-orienteringsmetoder. Vi vil se på språkets sterke og svake
|
|
sider, de viktigste grunnelementene samt mer avanserte ting som
|
|
komplekse datastrukturer og objekt-orientert programmering. Vi skal
|
|
også lage enkle og mer avanserte perl-script, bruke moduler og
|
|
dokumentere på en enkel måte. Perl under Microsoft-plattformer blir
|
|
gledelig ignorert - UNIX er tingen! :^)</TD><TD></TD></TR></TABLE></P>
|
|
|
|
|
|
<A NAME='C1'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 1: Hva er Perl?</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Liten</H3>
|
|
|
|
<CODE>perl -e 'print "Hello, World!\n";'</CODE>
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Åpen</H3>
|
|
|
|
"Practical Extraction and Report Language" er et fjerdegenerasjons
|
|
språk som er laget for "å få jobben gjort." Språket er over ti år
|
|
gammelt, og uvikles som et OSS-prosjekt av Larry Wall i samarbeid med
|
|
flere hundre mennesker fra hele verden. Perl og de aller fleste
|
|
modulene er lisensiert under "GNU Public License" eller "Artistic
|
|
License" - du velger selv.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Kraftig</H3>
|
|
|
|
Perl har flere GUI-moduler, støtter alle lavnivå
|
|
internettprotokollene, har uhyre kraftige tekstbehandlings-muligheter,
|
|
tillater både funksjonell og OO-programmering, har meget gode
|
|
database-API, og tillater det meste noen skulle trenge å programmere i
|
|
løpet av en dag.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>'Naturlig'</H3>
|
|
|
|
Perl er fra begynnelsen av blitt utviklet som et "naturlig" språk -
|
|
det vil si at det er så dynamisk at du kan gjøre nyttige ting selv om
|
|
du bare kan noen få ord, eller at du kan bruke år på å mestre hele
|
|
språket. Det er lett å lære seg nye elementer i språket, og det finnes
|
|
altids en nåte å uttrykke seg på som passer din programmeringsstil.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Til fare for liv og helse!</H3>
|
|
|
|
Dessverre er det for lett å programmere dårlig eller farlig i perl -
|
|
slikt kommer ofte med på kjøpet når man velger å bruke et kraftig
|
|
verktøy. Perl gir nok muligheter til at du ikke bare kan skyte deg
|
|
selv i foten, men faktisk gjøre det med stil, ekstravaganse og utrolig
|
|
letthet! Heldigvis har språket et par hjelpemidler så du unngår de
|
|
groveste dumhetene. Det gir derimot ikke grunn til å la være å passe
|
|
på!
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Litt større</H3>
|
|
|
|
Om du vil, kan du også bryne deg på litt "vanskeligere" ting. (Denne
|
|
er egentlig ikke så vanskelig! Etter kurset bør du kunne finne ut hva
|
|
som skjer.)
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl
|
|
# En obfuskert signaturfil?
|
|
($_='$ZNVYGB+$FWA?$CII:$BET;')?y:;ZA-Y\:?+${':\nm-za-l.@\:\0:?print:'}.':'.$';
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C2'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 2: Pathologically Eclectic Rubbish Lister</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Hva egner perl seg til?</H3>
|
|
|
|
<UL>
|
|
|
|
<LI>Vanlige og uvanlige systemadministrasjonsoppgaver.
|
|
</LI>
|
|
|
|
<LI>Nettverkskommunikasjon.
|
|
</LI>
|
|
|
|
<LI>CGI-programmering.
|
|
</LI>
|
|
|
|
<LI>"Rapid Prototyping."
|
|
</LI>
|
|
|
|
<LI>"Lim" mellom applikasjoner.
|
|
</LI>
|
|
|
|
<LI>Effektiv behandling av store mengder tekst (HTML? XML?
|
|
loggfiler?)
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Hva egner det seg ikke til?</H3>
|
|
|
|
<UL>
|
|
|
|
<LI>Svært store og/eller komplekse prosjekter.
|
|
</LI>
|
|
|
|
<LI>Arbeidsoppgaver der maskinressursene er knappe.
|
|
</LI>
|
|
|
|
<LI>Oppgaver det programmet krever svært rask utførelse og/eller høy
|
|
responstid.
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Men tenk over oppgaven!</H3>
|
|
|
|
Det er mulig perl ikke er den beste løsningen til akkurat din oppgave!
|
|
Det finnes mange språk, og vårt egner seg ikke til alt (selv om det
|
|
kan brukes til svært mye.) Om et skriptspråk er løsningen, ta gjerne
|
|
også en titt på Python, TCL, Scheme eller til og med Visual Basic -
|
|
alle disse har egne fordeler og ulemper. Noen ganger trenger du
|
|
ytelsen fra lavnivåspråk, og da er det meget mulig at Perl er feil
|
|
løsning.... Kanskje det smarteste er å lage en perl-modul i C? :^)
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C3'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 3: Latskap, Utålmodighet og Hovmod!</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Perl-programmererens tre dyder</H3>
|
|
|
|
<UL>
|
|
|
|
<LI>Latskap, fordi du velger å skrive kode en gang, slik at det også
|
|
kan brukes andre steder og av andre. Merk også at du dokumenterer
|
|
skikkelig, for da slipper du å svare på dumme spørsmål fra folk som
|
|
bruker koden din!
|
|
</LI>
|
|
|
|
<LI>Utålmodighet, fordi du ikke vil vente på datamaskinen hele
|
|
tiden, og heller passer på at koden din ikke bare reagerer på behovene
|
|
dine, men faktisk forutser dem!
|
|
</LI>
|
|
|
|
<LI>Hovmod, fordi det får deg til å skrive kode som andre ikke vil
|
|
kritisere.
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
Følg dem, og alt går så meget bedre!
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C4'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 4: Fordeler og Ulemper</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Plusspoeng</H3>
|
|
|
|
<UL>
|
|
|
|
<LI>Perl er et høynivå språk med tilgang på lavnivå kall om man
|
|
trenger det.
|
|
</LI>
|
|
|
|
<LI>Å programmere i perl går fort - man kan få mye effekt ut av få
|
|
linjer kode, noe som man kan oversette direkte til spart tid og
|
|
penger.
|
|
</LI>
|
|
|
|
<LI>Perl har et rikt utvalg av moduler som omhandler alt fra
|
|
kryptering og autentisering til verktøy som kan brukes i
|
|
molekylærbiologi og til å samle e-postaadresser på USENET. (Ikke gjør
|
|
det!)
|
|
</LI>
|
|
|
|
<LI>Perl har flere innebygde sikkerhetsfunksjoner, og et godt utvalg
|
|
med moduler som gjør livet lettere.
|
|
</LI>
|
|
|
|
<LI>Det går an å "vokse" med språket, siden det er enkelt, kraftig
|
|
og smidig. Det er alltid noe nytt du kan lære og et triks som gjør
|
|
programmeringen morsommere. (Perl er en skrekk for språkminimalister.)
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Minuspoeng</H3>
|
|
|
|
<UL>
|
|
|
|
<LI>Perl tar - og beholder - alt den trenger av ressurser. Det er
|
|
ikke vanskelig å sluke alle ressursene på en maskin om man ikke passer
|
|
på!
|
|
</LI>
|
|
|
|
<LI>Kildekoden i et perl-program kan lett gjøres uleselig! Prøv å
|
|
søke etter "Obfuscated Perl contest" på nettet, og forbered deg på en
|
|
stygg hodepine.
|
|
</LI>
|
|
|
|
<LI>Språket kan for enkelte være tungt å lære/bruke på grunn av
|
|
mengden med "spesialvariabler."
|
|
</LI>
|
|
|
|
<LI>Perl er en skrekk for språkminimalister. (Det går an å "vokse"
|
|
med språket, siden det er enkelt, kraftig og smidig. Det er alltid noe
|
|
nytt du kan lære og et triks som gjør programmeringen morsommere.)
|
|
</LI>
|
|
|
|
<LI>Språket lærer deg ikke å programmere godt/pent - det må du gjøre
|
|
selv! Ikke bli fristet til å skrive "bruk og kast-kode".
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C5'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 5: Datastrukturer i Perl</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
I perl opererer man i hovedsak med tre typer data (det finnes flere,
|
|
men de er ikke så viktige i starten.)
|
|
<UL>
|
|
|
|
<LI>"Scalar" - Et enkeltelement (tekst, tall, pekere, m.m.) -
|
|
<CODE>$foo</CODE>.
|
|
</LI>
|
|
|
|
<LI>"Array" - En liste av enkeltelementer, med tall fra null og
|
|
oppover som indeksverdier - <CODE>@bar</CODE>, <CODE>$bar[0]</CODE>
|
|
eller <CODE>$bar[$tall]</CODE>.
|
|
</LI>
|
|
|
|
<LI>"Hash" - En liste med navngitte indeksverdier i stedet for tall
|
|
("Hashes" ogr også kjent som "Assosiative Arrays") -
|
|
<CODE>%baz</CODE>, <CODE>$baz{tekst}</CODE> eller
|
|
<CODE>$baz{$indeks}</CODE>.
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
Variabler og datastrukturer trenger ikke å forhåndsdeklareres, men kan
|
|
istedet opprettes når man trenger dem. Dette betyr ikke at det er dumt
|
|
å deklarere dem på forånd! Faktisk, glem det jeg skrev om valgfri
|
|
forhåndsdeklarering, og lat som om du må gjøre det!
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C6'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 6: Scalars (skalare verdier?)</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
Skalare verdier angis ved å bruke en '$' foran
|
|
variabelnavnet. <CODE>$navn</CODE> vil angi at den enten er en streng,
|
|
et tall eller en referanse. I alle tilfeller vil variabelen kun
|
|
inneholde en eneste verdi.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $hilsen = 'heisann';
|
|
my $person = 'Per';
|
|
print "$hilsen, $person! Har du det bra?\n";
|
|
my( $svar, $tilstand ) = ( "joda", "bra" );
|
|
print "$svar, det går $tilstand.\n";
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
I mange programmeringsspråk (f.eks. C eller Pascal) deklarerer man
|
|
typen på variabelen (f.eks. "char* hilsen;") før den brukes, noe som
|
|
ikke er nødvendig i perl - et tall er en skalar, og ikke en integer,
|
|
float, double eller slikt. Bare husk å forhåndsdeklarere variablene
|
|
(selv om du ikke må.) Dette kan gjøres ved å bruke <CODE>my()</CODE>
|
|
foran variabelen, eller ved å deklarere dem globalt med <CODE>use vars
|
|
('$hilsen', '$person');</CODE>. Om du vil konkatenere strenger, kan du
|
|
bruke "<CODE>.</CODE>" (punktum) mollom strengene.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $tid = scalar localtime; # hva gjør scalar() ?
|
|
print "Vi fanget dette øyeblikket: " . $tid;
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
En viktig poeng:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $tekst = "foo";
|
|
print "Med doble fnutter: $tekst";
|
|
print 'Med enkle fnutter: $tekst'; # hva er forskjellen?
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C7'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 7: Arrays</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
|
|
En liste av "skalare verdier" indeksert med tall, der første
|
|
indeksverdi er null.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my @array = ( "a", "b", "c", "d" );
|
|
print $array[1]; # Skriver ut "b"
|
|
$array[2] = "foo";
|
|
print @array; # Skriver ut "afoocd"
|
|
print "@array"; # Med resultat "a foo c d"
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Det er verdt å merke seg at vi skriver ut et enkeltelement inni an
|
|
array som <CODE>$array[1]</CODE> og ikke som <CODE>@array[1]</CODE>!
|
|
Grunnen til dette er at vi vanligvis ønsker å få tak i en enkel verdi,
|
|
og ikke en array! Om du absolutt må ha en array som resultat, kan du
|
|
gjøre som så:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my @nok_en_array = @array[0,2];
|
|
print "@nok_en_array" # Vi får "a c"
|
|
my @enda_en_array = @array[0..2];
|
|
print "@enda_en_array" # Skriver ut "a foo c"
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Utover dette finnes det en del funksjoner som behandler "arrays", og
|
|
er par av disse er:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
push(@array, "verdi2");
|
|
my $var1 = pop(@array);
|
|
unshift(@array, "verdi2");
|
|
my $var2 = shift(@array);
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Et eksempel uten videre dyp forklaring...
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my @array = ("a", "b", "c");
|
|
my $last = pop(@array);
|
|
push(@array, "e");
|
|
my $first = shift(@array);
|
|
unshift(@array, "d");
|
|
print @array; # Skriver ut "dbe"
|
|
|
|
foreach my $verdier (@array) {
|
|
print "$verdier\n";
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C8'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 8: Hashes (assosiative arrays?)</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
En assosiativ array, eller "hash", består av tilordnede
|
|
nøkkel- og verdi-par hvor nøkkelen peker til en verdi:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my %hash = (key1 => 1,
|
|
key2 => "tekst",
|
|
key3 => 3);
|
|
print $hash{key1}; # Skriver "1"
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Merk at vi også her bruker '$' for å trekke ut en skalar
|
|
verdi. For å gå igjennom alle verdiene i en hash så
|
|
kan man bruke følgende prosedyre:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
foreach my $key (keys %hash) {
|
|
print "$key => $hash{$key}\n";
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Denne vil gå igjennom alle nøklene og verdiene for deretter å skrive
|
|
dem ut. Nøkkelfunksjonen her er <CODE>keys</CODE> (pun intended), som
|
|
returnerer alle nøklene i <CODE>%hash</CODE> (tilsvarende finnes det
|
|
en en <CODE>values</CODE> funksjon). Man kan selvfølgelig utvide dette
|
|
for å gjøre mer komplekse ting med hashen f.eks:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my %count_hash;
|
|
foreach my $key (sort keys %hash) {
|
|
# teller antall forekomster av bestemte verdier i en hash.
|
|
++$count_hash{$hash{$key}};
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C9'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 9: Subrutiner i perl</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
Bruk <CODE>my();</CODE>! Dette er spesielt viktig i funksjoner
|
|
så variablene er unike for den navnerom de blir deklarert
|
|
i. Godt tips som du allerede bør vite: Bruk aldri globale
|
|
variabler! De skaper bare problemer.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
print pluss(7, 77); # Skriver ut "84"
|
|
|
|
sub pluss {
|
|
my( $argument1, $argument2 ) = @_; # Argumenter ligger i @_
|
|
return $argument1 + $argument2;
|
|
}
|
|
|
|
print pluss(4, 19); # Skriver ut "23"
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Det er også likegyldig hvor i programemt vi definerer funksjonen
|
|
- det er ditt ansvar å skrive ryddig kode!
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C10'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 10: Hvordan kjøre et perl-script</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
Følgende punkter må være i orden for at programmet skal kunne kjøre:
|
|
<UL>
|
|
|
|
<LI>Maskinen du logger inn på på ha perl installert! Dette kan du
|
|
finne ut med <CODE>which perl</CODE>.
|
|
</LI>
|
|
|
|
<LI>Pass på at du har en ny versjon av perl. Dette kan du finne ut
|
|
med <CODE>perl -v</CODE>. Versjon 5.004_04 eller nyere er bra, 5.003
|
|
eller nyere går an, og om du har noe eldre en det, oppgrader. Om du
|
|
skulle være uheldig nok til å ha en versjon 4 perl, så bli kvitt den
|
|
med en gang! Perl 4 er død, og vil aldri mere bli oppdatert!
|
|
</LI>
|
|
|
|
<LI>Lag en fil og plasser i toppen av fila. Første bokstav i fila
|
|
skal være "#"! Strengt tatt er ikke <CODE>-wT</CODE>, <CODE>use
|
|
strict;</CODE> og <CODE>use diagnostics;</CODE> nødvendig, men de er
|
|
fryktelig nyttige å ha der mens du lager programmet - når du er ferdig
|
|
kan du ta dem vekk igjen.
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -wT
|
|
|
|
use strict;
|
|
use diagnostics;
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
<UL>
|
|
|
|
<LI>Pass på å erstatte <CODE>/usr/bin/perl</CODE> med resultatet til
|
|
<CODE>which perl</CODE> om det er ulikt, ellers vil du ikke få kjørt
|
|
programmet.
|
|
</LI>
|
|
|
|
<LI>Det er viktig at fila er eksekverbar! Dette fikser du med
|
|
<CODE>chmod(1)</CODE> kommandoen. <CODE>man chmod</CODE> hjelper
|
|
deg der om du ikke er kjent med kommandoen.
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C11'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 11: Spesielle variabler</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
De "spesielle variablene." De er ofte sett på som det "mest ekle" ved
|
|
perl, og det er de som tillater å skrive et program virkelig raskt -
|
|
på godt og ondt. Du slipper ikke unna dem! En spesiell detalj ved
|
|
disse, er at du ikke kan bruke <CODE>my();</CODE> for å gjøre dem til
|
|
lokale variabler. Som oftest gjør ikke det noe, men om du
|
|
f.eks. ønsker å endre an spesialvariabel inni en subrutine, uten at
|
|
"orginalen" blir ødelagt, bruk <CODE>local();</CODE>. Merk at det
|
|
finnes mange fler, men det er som oftest disse du vil møte først.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>@ARGV</H3>
|
|
|
|
...Er et predefinert array som inneholder kommandolinjeargumentene. Om
|
|
du kjører perl-scriptet <CODE>test.pl</CODE> med parameter
|
|
<CODE>"start"</CODE> vil argumentet bli plassert <CODE>$ARGV[0]</CODE>
|
|
(og tilsvarede <CODE>$ARGV[1]</CODE> for det andre argumenter, osv.)
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>@_</H3>
|
|
|
|
<CODE>@_</CODE> er et predefinert array som brukes til å
|
|
gjøre argumentene til en funksjon tilgjengelig inni
|
|
funksjonen. Dette vil si at alle subrutiner mottar argumentene sine i
|
|
et array - noe som tillater en vilkårlig mengde parametere!
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
sub foo { print $_[1] } # Skriver ut andre argument i @_
|
|
|
|
foo("A", "B", "C"); # "B" blir skrevet ut!
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>$_</H3>
|
|
|
|
<CODE>$_</CODE> er meget spesiell. Dette er "default-variabelen"!
|
|
Svært mange funksjoner i perl godtar å bli kjørt
|
|
uten parametere i det hele tatt, eller uten å vise til hvilke
|
|
variabler som blir behandlet. Når dette er tilfelle, vil alltid
|
|
innholdet i <CODE>$_</CODE> bli brukt!
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
$_ = "En test\n";
|
|
print; # Skriver ut "En test\n"
|
|
|
|
my @array = ( 1, 1, 2, 3, 5, 8, 13, 21 );
|
|
foreach ( @array ) { # Et og et element i @array blir plassert i $_
|
|
print; # ... og skrevet ut!
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>$!</H3>
|
|
|
|
Denne variabelen inneholder feilmeldingsteksten til den siste feilen
|
|
som oppstod. For eksempel om du prøver å åpne en fil for lesing, og
|
|
feiler, vil årsaken til feilen stå der.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $filnavn = "/etc/passswd";
|
|
open( FIL, "<$filnavn" ) || die "Kan ikke lese fra '$filnavn': $!\n";
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>$0</H3>
|
|
|
|
<CODE>$0</CODE> inneholder programnavnet.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>%ENV</H3>
|
|
|
|
Inneholder miljøvariablene! Vil du vite hva $USER er satt til?
|
|
<CODE>print $ENV{USER};</CODE>!
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>$@</H3>
|
|
|
|
Inneholder en eventuell feilmelding fra filsystemet om et system-kall
|
|
har feilet. (Mere om <CODE>system()</CODE> kommer senere!)
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
system("ls -l", "/dev/nosuchthing", "/etc", "/usr");
|
|
die "Error: $@\n" if defined $@;
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C12'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 12: Exterior: Dagobah -- day</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
With Yoda strapped to his back, Luke climbs up one of the many thick
|
|
vines that grow in the swamp until he reaches the Dagobah statistics
|
|
lab. Panting heavily, he continues his exercises -- grepping,
|
|
installing new packages, logging in as root, and writing replacements
|
|
for two-year-old shell scripts in Python.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Yoda:</H3>
|
|
|
|
Code! Yes. A programmer's strength flows from code maintainability.
|
|
But beware of Perl. Terse syntax... more than one way to do it...
|
|
default variables. The dark side of code maintainability are they.
|
|
Easily they flow, quick to join you when code you write. If once you
|
|
start down the dark path, forever will it dominate your destiny,
|
|
consume you it will.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Luke:</H3>
|
|
|
|
Is Perl better than Python?
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Yoda:</H3>
|
|
|
|
No... no... no. Quicker, easier, more seductive.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Luke:</H3>
|
|
|
|
But how will I know why Python is better than Perl?
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Yoda:</H3>
|
|
|
|
You will know. When your code you try to read six months from now.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
(Funnet på rec.humor.funny, og gjengitt uten tillatelse
|
|
siden forfatter er ukjent. ;^)
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C13'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 13: Enda flere spesielle variabler</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Åh nei...</H3>
|
|
|
|
Joda. Det finnes mange, og vi tar et par til som er kjekke å vite om.
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>$/</H3>
|
|
|
|
<CODE>$/</CODE> kalles "the input record seperator", og bestemmer hva
|
|
som skal være skilletegnet mellom hvert element su leser fra en
|
|
filehandle. Standardverdi er <CODE>"\n"</CODE>, som medfører at man
|
|
leser kun en linje om gangen.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
open( PASSWD, "/etc/passwd" ) || die "Kan ikke lese: $!";
|
|
|
|
my $line = <PASSWD>;
|
|
print $line;
|
|
# "navnsen:sEp4D.g/dg:6000:133:Etter Navnsen:/home/navnsen:/bin/false\n"
|
|
|
|
local( $/ ) = ":";
|
|
|
|
my $field = <PASSWD>;
|
|
close( PASSWD );
|
|
|
|
print $field;
|
|
# "navnsdottir:"
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>$\</H3>
|
|
|
|
"Output record seperator" er skilletegnet mellom hvert element i et
|
|
array! Standardverdi er <CODE>""</CODE>, så det dukker ikke opp noe
|
|
mellom hvert element.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my @stuff = qw( datamaskin sykkel dress bestikk );
|
|
|
|
print @stuff;
|
|
# "datamaskinsykkeldressbestikk"
|
|
|
|
local( $\ ) = " OG ";
|
|
|
|
print @stuff;
|
|
# "datamaskin OG sykkel OG dress OG bestikk"
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C14'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 14: Filbehandling</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Hvordan leser man fra en fil?</H3>
|
|
|
|
Pass på å sjekke returverdier, hva en du åpner!
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
open( FILE, "<fil.txt" )
|
|
|| die "Kan'ke lese fila 'fil.txt': $!\n";
|
|
while ( <FILE> ) {
|
|
# Gjør noe nyttig her.
|
|
print;
|
|
}
|
|
close FILE || die "Kainn ittj' lukk fil.txt? $!\n";
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Hvordan skriver man til en fil?</H3>
|
|
|
|
Sjekk av returverdi! Sjekk returverdi!
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
open( FILE, ">fil.txt" )
|
|
|| die "Kan'ke skriv te 'fil.txt': $!\n";
|
|
print FILE "første linje\n";
|
|
close FILE || die "Kainn ittj' lukk fil.txt? $!\n";
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C15'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 15: open()</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>En liten oversikt over hva open() kan gjøre</H3>
|
|
|
|
Man bruker open til å kjøre klar filen for skriving eller lesing, og
|
|
oppretter i prosessen en "filehandle" som man bruker under resten av
|
|
behandlingen. I vårt tilfelle heter den FILE. Her kommer en liten
|
|
oversikt over de forskjellige måtene å bruke <CODE>open</CODE> på:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
open(F, "fil"); # lesing
|
|
open(F, "<fil"); # lesing -eksplisitt
|
|
open(F, ">fil"); # skriving
|
|
open(F, "+>fil"); # les og skriv
|
|
open(F, ">>fil"); # tillegg (legge til på slutten)
|
|
open(F, "|cmd"); # skriv til kommando
|
|
open(F, "cmd|"); # les fra kommando
|
|
open(F, "|-"); # skriv til fork
|
|
open(F, "-|"); # les fra fork
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>The diamond operator</H3>
|
|
|
|
En spesiell filehandle en "the diamond operator"
|
|
<CODE><></CODE>. Om programmet ditt ikke tr noen argumenter vil
|
|
<CODE><></CODE> lese fra STDIN. I motsatt tilfelle vil alle
|
|
argumentene kunne tolkes som filnavn og automatisk leses inn. Det går
|
|
ikke an å skrive til "the diamond operator".
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -w
|
|
# Et lite program som kommenterer ut hele filer.
|
|
#
|
|
use strict;
|
|
|
|
while ( <> ) {
|
|
print "# $_";
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C16'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 16: Betingelser og Kontrollstrukturer</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
Perl inneholder selvfølgelig de fleste kontrollstrukturene man har
|
|
bruk for...
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -w
|
|
|
|
print "Skriv et tall: ";
|
|
$tall = <STDIN>;
|
|
chomp($tall); # fjerne linjeskift
|
|
if ( $tall > 0 ) {
|
|
print "positivt tall\n";
|
|
elsif ($tall < 0) {
|
|
print "negativt tall\n";
|
|
} else {
|
|
print "tallet er 0\n";
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Forøvrig finnes det et par andre varianter av <CODE>if</CODE>-testen:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
unless ($tall == 2) {
|
|
print "tallet er ikke 2";
|
|
}
|
|
|
|
# Prøv "baklengs" notasjon! :
|
|
print "God dag!\n" $natt && $a_menneske;
|
|
|
|
# Eller hva med "kort-notasjonen"?
|
|
my $tall = 0;
|
|
print $tall ? "sann\n" : "usann\n";
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C17'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 17: Logiske operatorer</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
|
|
Perl har to logiske operatorer, <CODE>&&</CODE> (AND) og
|
|
<CODE>||</CODE> (OR). Begge er kortsluttende! dette betyr at "andre
|
|
halvdel" ikke blir sjekket med mindre første halvdel er henholdscis
|
|
sann (for AND) eller usann (for OR). I tillegg finnes <CODE>or</CODE>
|
|
og <CODE>and</CODE>, men ikke bruk de, for de fungerer på en litt
|
|
annerledes måte.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
$tall == 2 && print "tallet er 2\n";
|
|
$tall == 2 || print "tallet er ikke 2\n";
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C18'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 18: Sannhetsverdier</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Hva er sant?</H3>
|
|
|
|
Vi snur heller på spørsmålet - Hva er usant?
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
print "Dette skal ikke skrives ut\n"
|
|
if ("" || "0" || 0 || undef);
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Alt annet tar perl som god fisk - om du fikk 1, "ingen" eller "-99"
|
|
fisk vil perl være enig med deg. En liten detalj: perl tror deg dersom
|
|
du sier du fikk "0.0" fisk! Dvs. "0.0" er sann... :)
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C19'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 19: Løkker</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>While og Until-løkker</H3>
|
|
|
|
<CODE>while</CODE>-løkker blir kjørt såfremt startbetingelsen er
|
|
møtt. I det startbetingelsen ikke lenger er sann vil programmet gå ut
|
|
av løkken.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $tall = 0;
|
|
while ($tall < 10) {
|
|
$tall++;
|
|
print "nå er løkken kjørt $tall ganger\n";
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Løkker kan også skrives som ...
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
until( $event ) {
|
|
# gjør noe her.
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
... som tilsvarer <CODE>while( ! $event )</CODE>
|
|
|
|
</P>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>For-løkker</H3>
|
|
|
|
Denne bør være kjent.
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
for( $i = 0; $i <= 10; $i++ ) {
|
|
print $i;
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C20'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 20: Kall på eksterne programmer</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>`backticks` og system()</H3>
|
|
|
|
Ikke sjeldent vil det være interessant å starte opp eksterne
|
|
programmer i et perl-script. For eksempel ønsker man å sende et
|
|
e-brev, og starter sendmail for å gjøre dette, eller man vil ha en
|
|
oversikt over hvilke prosesser som er i gang på maskinen. Det finne
|
|
flere måter å gjøre dette på, og 'backticks' er en:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $tidspunkt = `date`; # Henter klokkeslett og dato fra date(1)
|
|
# og legger den i $tidspunkt
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Det er bakoverfnuttene (<CODE>``</CODE>) som forteller perl at den
|
|
skal kjøre en system-kommando. Bakoverfnuttene fungerer også som
|
|
vanlige fnutter, ved at variabler blir interpolert.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $foo = system("date"); # Skriver ut (!) dato, og setter $foo
|
|
# til enten 0 eller et tall med statuskoder
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Ta en titt på <CODE>perldoc -tf system</CODE> om du trenger å forstå
|
|
returverdiene.
|
|
</P>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>exec() - og open() igjen</H3>
|
|
|
|
<CODE>exec()</CODE> gjør det samme som <CODE>system()</CODE> men den
|
|
eneste forskjellen at perl-prosessen din ditt blir erstattet av
|
|
programmet du <CODE>exec()</CODE>'er.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
exec( $program, "arg1", "arg2" );
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
I tillegg kan man bruke <CODE>open()</CODE> som vi husker fra
|
|
filbehandlingsdelen:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
open( LS, "ls|" ) || die "Kunne ikke åpne ls: $!\n";
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C21'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 21: Faremomenter ved kall på eksterne programmer!</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Hva kan gå galt?</H3>
|
|
|
|
Gitt følgende uheldige scenario:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $argument = '/etc; rm -rf / >&- 2>&- &';
|
|
# Dette kan komme fra en ekstern kilde! kanskje du
|
|
# leste inn parametere fra <STDIN>?
|
|
|
|
system("ls -l $argument"); # Oops!
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Ingen ønsker å oppleve dette - derfor er det viktig å passe på å lage
|
|
perl-programmene sine skikkelige - SPESIELT HVIS ANDRE SKAL BRUKE
|
|
DEM!!
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Hvordan unngå å drite seg ut?</H3>
|
|
|
|
Et par gode triks er:
|
|
<UL>
|
|
|
|
<LI>Unngå å bruke <CODE>``</CODE>, <CODE>system()</CODE>,
|
|
<CODE>exec()</CODE>, <CODE>open()</CODE>, <CODE>opendir()</CODE>,
|
|
<CODE>syscall()</CODE>, <CODE>glob()</CODE> og andre funksjoner som
|
|
aksesserer systemet.
|
|
</LI>
|
|
|
|
<LI>Bruk <CODE>-T</CODE> (taint-checking) som parameter til perl!
|
|
</LI>
|
|
|
|
<LI>Om du må bruke <CODE>system()</CODE> og tilsvarende funksjoner,
|
|
pass på å bruke lister som argumenter i stedet for tekststrenger. Om
|
|
du bruker en tekststreng for to eller flere ord sammen, så vil perl
|
|
starte et eget skall for å "gjøre fornuft" av
|
|
parameterene. <CODE>system("ls -l $dir1 $dir2")</CODE> er farlig, men
|
|
<CODE>system("ls", "-l", $dir1, $dir2)</CODE> er OK.
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C22'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 22: Regulære uttrykk (regular expressions)</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Perl sitt mest berømte våpen</H3>
|
|
|
|
Regexp er perl sin største og mest populære styrke. Man kan med svært
|
|
enkle konstuksjoner representere komplekse data. Regulære uttrykk blir
|
|
oftest brukt til analyse, eller uthenting og endring av data i store
|
|
mengde tekst.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -w
|
|
#
|
|
use strict;
|
|
|
|
while( my $logglinje = <> ) {
|
|
print ++$teller,": $logglinje" if m/^mandag/;
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Her er kortversjonen av hva som er mulig med regulære uttrykk:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
bokstav matcher seg selv
|
|
tall matcher seg selv
|
|
\. matcher et punktum
|
|
\tegn matcher et tegn
|
|
\\ matcher \
|
|
. matcher alle tegn unntatt "\n"
|
|
[abc] matcher a, b eller c
|
|
[a-z] matcher a, b,... y, z
|
|
[^abc] matcher alt unntatt a,b eller c
|
|
\w [a-zA-Z0-9_]
|
|
\W [^\w]
|
|
\s matcher "whitespace"
|
|
\S alt annet en whitespace
|
|
\d [0-9]
|
|
\D [^0-9]
|
|
\n matcher newline
|
|
\t matcher tab
|
|
\b matcher begynnelsen eller slutten av et ord
|
|
\032 matcher tegn tilsvarende oktalverdien gitt
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
For å enkelt lage kraftigere uttrykk trenger vi flere elementer
|
|
("Kvantifiserere"?).
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
* matcher 0 eller flere ganger
|
|
+ matcher 1 eller flere ganger
|
|
? matcher 1 eller 0 ganger
|
|
{n} matcher nøyaktig n ganger
|
|
{n,} matcher minst n ganger
|
|
{n,m} matcher minst n og maks m ganger
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Grådige uttrykk</H3>
|
|
|
|
I utgangspunktet er alle "Kvantifiserere" grådige - de ønsker å matche
|
|
mest mulig, og om de få sjansen gjør de det. Det er ikke alltid vi er
|
|
interessert i dette - noen ganger er vi f.eks. interessert i å få
|
|
teksten mellom to apostrofer, men det er flere apostrofer på samme
|
|
linje! For å unngå dette, kan vi legge til et spørsmålstegn etter
|
|
"kvantifikatoren", så vil den prøve å matche minst mulig.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $test = '"hah" sa han. Hunden ytret et "voff!"';
|
|
$test =~ m/"(.*)"/;
|
|
print $1; # Skriver ut 'hah!" sa han. Hunden ytret et "voff!'
|
|
$test =~ m/"(.*?)"/;
|
|
print $1; # Skriver ut '"hah!"'
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Det går også an å legge til "ankre"! Hvis vi vet at en bestemt tekst
|
|
er ved begynnelsen eller ved slutten av en linje, går det an å
|
|
bruke. I tillegg bør du vite at man kan
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
^ matcher begynnelsen av linjen
|
|
$ matcher slutten av linjen
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Og for å utføre en operasjon med regulære uttrykk, kan du gjøre.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -w
|
|
|
|
my @rest;
|
|
while( <> ) {
|
|
s/\r//g; # Fjerner ^M fra slutten av linja
|
|
s/[æøåÆØÅ]/./g; # Erstatter alle æ, ø og å med punktum
|
|
tr/a-z/A-Z/; # Gjør om små bokstaver til store
|
|
m/(ab){2,4}/i; # matcher på abab (el.l.) uten å bry
|
|
# seg om store eller små bokstaver
|
|
push(@rest, $_);
|
|
}
|
|
|
|
my @foos = grep( ! /foo/i, @rest ); # vi trenger linjene uten "foo"
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Regexp-operatorer</H3>
|
|
|
|
Du kan forandre hvordan et regulært uttrykk fungerer ved å legge til
|
|
en eller flere operatorer etter uttrykket. De vanligste er
|
|
<CODE>m//gimsx;</CODE> - det finnes fler, men de bryr vi oss ikke om
|
|
nå.
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
g Matcher uttrykket globalt
|
|
i Ignorere store/små bokstaver
|
|
m Behandle dataene over flere linjer
|
|
s Behandle dataene som om de var på en linje
|
|
x Ignorere "unescaped whitespace" - Gjør
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C23'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 23: Nøstede datastrukturer</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Referansemagi</H3>
|
|
|
|
Nøstede datastrukturer, det vil si datastrukturer inni datastrukturer
|
|
lager vi med hjelp av referanser. Eksempler kan være flerdimensjonelle
|
|
arrays eller hasher av hasher.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my @array = ('foo',
|
|
'bar',
|
|
['a', 2, 'c'],
|
|
{key1 => "verdi1",
|
|
key2 => "verdi2"}
|
|
);
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Her har vi en array som inneholder fire elementer. De to første er
|
|
skalare, det tredje er en anonym array, og det fjerde en anonym hash. Gitt koden ovenfor, er følgende utsagn sanne:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
$array[0} == 'foo';
|
|
$array[2]->[1] == 2;
|
|
$array[3]->{key2} == 'verdi2';
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Vi kan lage en referanse til <CODE>@array</CODE>, og om vi gjør det
|
|
vil ting bli mer interessante. Gitt første uttrykk her, så er resten
|
|
sanne:
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
my $aref = \@array;
|
|
$aref->[1] == 'bar';
|
|
$aref->[3]->{key1} == 'verdi1';
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
Alt dette kan kombineres hvordan du vil - bar husk å holde orden!
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C24'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 24: Moduler og 'package'</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>En enkel modul</H3>
|
|
|
|
Prøv! Dette er ikke komplisert.
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
# Vi starter med å lage en fil som vi kaller Hello.pm
|
|
|
|
package Hello; # Samme navn som fila, men uten ".pm"
|
|
|
|
# Om fila het Hello/World.pm, må vi kalle pakken Hello::World
|
|
|
|
sub person {
|
|
my $navn = shift;
|
|
my $kjonn = shift;
|
|
|
|
die "person() skal ha 2 argumenter" unless @_ == 0;
|
|
die "$navn sitt kjønn må være 'M' eller 'K'! (ikke '$kjonn')\n"
|
|
unless $kjonn =~ m/^[MK]$/;
|
|
|
|
return [ $navn, $kjonn, 0 ]; # siste tallet er en "hilse-teller"
|
|
}
|
|
|
|
sub hils {
|
|
my $person = shift; # vi venter oss returverdien fra person()
|
|
my $hva = $person->[1] eq "M" ? "han" : "hun";
|
|
my $hvem = $person->[0];
|
|
|
|
$person->[2]++; # hvor mange ganger $person er blitt hilst på?
|
|
|
|
print "Nei, se! Der har vi jo $hva $hvem!\n";
|
|
}
|
|
|
|
sub vis_ant_hilsninger {
|
|
my $person = shift;
|
|
my $hvem = $person->[0];
|
|
my $ant = $person->[2];
|
|
print "Vi har hilset på $hvem $antall gang",
|
|
( $ant-1 ? "" : "er" ), "\n";
|
|
}
|
|
|
|
1; # det er viktig at alle moduler returnerer en sann verdi!
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
# Ny fil! Dette er "hils.pl"
|
|
|
|
package main; # Hoved-navnerommet heter "main", og trengs ikke å
|
|
# annonseres på denne måten, egentlig. Med mindre vi
|
|
# har flere "package" i samme fil...
|
|
|
|
my $friend1 = Hello::person("Gorm", "M");
|
|
|
|
my @other_friends = (
|
|
Hello::person("Natalija", "M"),
|
|
Hello::person("Remi", "M") );
|
|
|
|
# Og så hilser vi po et par venner :)
|
|
|
|
Hello::hils( $friend );
|
|
Hello::hils( $other_friends[0] );
|
|
Hello::hils( $other_friends[1] );
|
|
Hello::hils( $friend );
|
|
Hello::hils( $other_friends[0] );
|
|
Hello::hils( $friend );
|
|
Hello::vis_ant_hilsninger( $friend );
|
|
Hello::vis_ant_hilsninger( $other_friends[0] );
|
|
Hello::vis_ant_hilsninger( $other_friends[1] );
|
|
|
|
__END__
|
|
|
|
Ferdig! Vi kunne ha fått penere kode ved å importere symbolene fra
|
|
Hello.pm, men da mister vi fordelen av å vite nøyaktig hvilken pakke
|
|
funksjonene hører til i.
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C25'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 25: OO-programmering</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Litt om hva som finnes</H3>
|
|
|
|
Objekt-orientert programmering i perl er en litt pussig opplevelse. En
|
|
del av OO-teorien er blitt droppet! - det finnes f.eks. ikke egne
|
|
"public" eller "private" -egenskaper. Enkapsulasjon må programmereren
|
|
selv sørge for å ikke bryte. Perl-objekter har likevel de viktigste
|
|
elementene som modularitet, arv (også multippel arv, om vi trenger
|
|
det), polymorfisme og annet. En klasse i perl lages ved å opprette en
|
|
fil med en egen pakke i seg, og passe på at det finnes en
|
|
konstruktor. Funkjonene i pakken er da metodene i klassen, globale
|
|
variabler i pakkens navneromm bli klasse-variabler, og variablen
|
|
konstrukoren returnerer blir objekt-variabler. Verre er det ikke!
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
# Vi vi prøver oss på nytt, og lager en fil som vi kaller Hello.pm
|
|
|
|
package Hello; # Som før...
|
|
|
|
sub new { # Vanlig navn på en konstruktor er "new" - ingen tvang!
|
|
my $package = shift; # første argument er alltid en referanse
|
|
# til
|
|
my $navn = shift;
|
|
my $kjonn = shift;
|
|
|
|
die "new() skal ha 2 argumenter" if @_;
|
|
die "$navn sitt kjønn må være 'M' eller 'K'! (ikke '$kjonn')\n"
|
|
unless $kjonn =~ m/^[MK]$/;
|
|
|
|
my $person = {
|
|
navn => $navn,
|
|
kjonn => $kjonn,
|
|
_ant_hils => 0 };
|
|
|
|
bless( $person, $package ); # Her knytter vi $person til
|
|
# $package, slik at vi får
|
|
# effekten av en klasse.
|
|
return $person;
|
|
}
|
|
|
|
sub hils {
|
|
my $self = shift;
|
|
my $hva = $self->{kjonn} eq "M" ? "han" : "hun";
|
|
my $hvem = $self->{navn};
|
|
|
|
$self->{_ant_hils}++; # hvor mange ganger "jeg" er blitt hilst på?
|
|
|
|
return "Nei, se! Der har vi jo $hva $hvem!\n";
|
|
}
|
|
|
|
sub vis_ant_hilsninger {
|
|
my $self = shift;
|
|
return $self->{_ant_hils};
|
|
}
|
|
|
|
sub vis_navn {
|
|
my $self = shift;
|
|
return $self->{navn};
|
|
}
|
|
|
|
sub vis_kjonn {
|
|
my $self = shift;
|
|
return $self->{kjonn};
|
|
}
|
|
|
|
1; # Så avslutter vi med en sann verdi.
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -w
|
|
# Ny fil! Dette er "hils.pl"
|
|
|
|
use strict;
|
|
use diagnostics;
|
|
|
|
use Hello; # Hello.pm må være tilgjegelig i @INC for at dette skal
|
|
# fungere smertefritt.
|
|
|
|
my $friend = Hello->new("Gorm", "M");
|
|
|
|
my @other_friends = (
|
|
Hello->new("Natalija", "M"),
|
|
Hello->new("Remi", "M") );
|
|
|
|
# Og så hilser vi po et par venner :)
|
|
|
|
print $friend->hils();
|
|
print $other_friends[0]->hils();
|
|
print $other_friends[1]->hils();
|
|
print $other_friends[1]->hils();
|
|
print $friend->hils();
|
|
print $other_friends[1]->hils();
|
|
print $other_friends[0]->hils();
|
|
|
|
print $friend->vis_ant_hilsninger();
|
|
print $other_friends[0]->vis_ant_hilsninger();
|
|
print $other_friends[1]->vis_ant_hilsninger();
|
|
|
|
__END__
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C26'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 26: En CGI-modul</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>CGI_Lite</H3>
|
|
|
|
En lett-versjon av den (mye) kraftigere CGI-modulen i perl - denne
|
|
passer bedre til enkle oppgaver, og er ikke så tung for systemet.
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -wT
|
|
#
|
|
# Et enkelt CGI-script som returnerer data du har gitt.
|
|
|
|
use strict;
|
|
use diagnostics;
|
|
use CGI_Lite;
|
|
|
|
my $cgi = new CGI_Lite; # En annen måte å lage et objekt på
|
|
|
|
$cgi->set_platform("Unix");
|
|
$cgi->add_mime_type("text/html");
|
|
|
|
my %form = $cgi->parse_form_data; # Hente inn data fra browser
|
|
|
|
$/ = undef; # Vi vil ha alt på en gang når vi leser fra en filehandle
|
|
|
|
my $page = <DATA> # Leser fra __DATA__ nedenfor
|
|
|
|
foreach my $data_key (keys %form) {
|
|
# Bytte ut f.eks. $NAVN med $form{NAVN}
|
|
$page =~ s/\$$data_key/$form{$data_key}/gm;
|
|
}
|
|
|
|
$page =~ s/\$\w+/foo/gm;
|
|
|
|
print "Content-type: text/html\r\n\r\n";
|
|
print $page;
|
|
|
|
__DATA__
|
|
<HTML>
|
|
<HEAD><TITLE>CGI_Lite-test</TITLE></HEAD>
|
|
<BODY>
|
|
|
|
<H1>Hei, $NAVN</H1>
|
|
|
|
Du er $ALDER gammel, har jeg hørt!
|
|
|
|
<HR>
|
|
|
|
<FORM METHOD="POST" ACTION="$SCRIPT_URL">
|
|
Navn: <INPUT TYPE="text" NAME="NAVN" VALUE="$NAVN"><BR>
|
|
Alder: <INPUT TYPE="text" NAME="ALDER" VALUE="$ALDER"><BR>
|
|
<INPUT TYPE="submit">
|
|
</FORM>
|
|
|
|
</BODY>
|
|
</HTML>
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C27'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 27: Referanser</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Nyttige linker</H3>
|
|
|
|
<UL>
|
|
|
|
<LI>Kurssidene til PVV - <A HREF='http://www.pvv.ntnu.no/kurs/'>http://www.pvv.ntnu.no/kurs/</A>
|
|
|
|
</LI>
|
|
|
|
<LI>Perl.com - Hovedressursern for perl-informasjon på nettet. Her
|
|
kan du søke i dokumentasjon, følge diskusjoner, lese artikler, få med
|
|
deg perl-nyheter go mye mer - <A HREF='http://www.perl.com/'>http://www.perl.com/</A>
|
|
|
|
</LI>
|
|
|
|
<LI>CPAN - "Comprehensive Perl Archive Network" er et sentralt
|
|
samlested for perl-moduler - <A HREF='http://www.perl.com/CPAN'>http://www.perl.com/CPAN</A>
|
|
|
|
</LI>
|
|
|
|
<LI>Perl Reference Topics - en meget bra oversikts-side over
|
|
dokumentasjon - <A HREF='http://www.perl.com/reference/'>http://www.perl.com/reference/</A>
|
|
|
|
</LI>
|
|
|
|
<LI>comp.lang.perl.* - Nyhetsgrupper for perl-interesserte. Et par
|
|
ukers "lurking" på disse kanalene er utrolig lærerikt! -
|
|
<A HREF='news:comp.lang.perl.misc'>news:comp.lang.perl.misc</A>
|
|
|
|
</LI>
|
|
|
|
<LI>FMTEYEWTK - "Far More Than Everything You've Ever Wanted to Know
|
|
About..." - <A HREF='http://www.perl.com/CPAN/doc/FMTEYEWTK/'>http://www.perl.com/CPAN/doc/FMTEYEWTK/</A>
|
|
|
|
</LI>
|
|
|
|
<LI>"The GNU Public License" -
|
|
<A HREF='http://www.opensource.org/licenses/gpl-license.html'>http://www.opensource.org/licenses/gpl-license.html</A>
|
|
|
|
</LI>
|
|
|
|
<LI>"The Artistic License" -
|
|
<A HREF='http://www.opensource.org/licenses/artistic-license.html'>http://www.opensource.org/licenses/artistic-license.html</A>
|
|
|
|
</LI>
|
|
|
|
<LI>"How To Write Unmaintainable Code" -
|
|
<A HREF='http://mindprod.com/unmain.html'>http://mindprod.com/unmain.html</A>
|
|
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Online dokumentasjon</H3>
|
|
|
|
<UL>
|
|
|
|
<LI><CODE>perldoc</CODE> er perl sitt plattformuavhengige
|
|
dokumentasjons-system - prøv å kjøre <CODE>perldoc perl</CODE>!
|
|
</LI>
|
|
|
|
<LI>perldoc
|
|
<UL>
|
|
|
|
<LI>perl - For å få oversikten.
|
|
</LI>
|
|
|
|
<LI>perlstyle - Hvordanskrive ryddig kode.
|
|
</LI>
|
|
|
|
<LI>perlfaq - Mange spørsmål med gode svar!
|
|
</LI>
|
|
|
|
<LI>perldata - Datastrukturer
|
|
</LI>
|
|
|
|
<LI>perlre - Regulære uttrykk
|
|
</LI>
|
|
|
|
<LI>perlfunc - Funksjoner Extravaganza!
|
|
</LI>
|
|
|
|
<LI>perlrun - Hva kan du skrive på kommandolinja?
|
|
</LI>
|
|
|
|
<LI>perltoot - Et mini-kurs i Objekt-orientert perl!
|
|
</LI>
|
|
|
|
<LI>perlsec - Om sikkerhet, og hva du bør tenke på.
|
|
</LI>
|
|
|
|
<LI>perlpos - Hvordan lage enkel, profesjonell inline
|
|
dokumentasjon.
|
|
</LI>
|
|
|
|
<LI>perlvar - Spesialvariabler...
|
|
</LI>
|
|
|
|
<LI>perltrap - Programmeringsfeller man kan gå i.
|
|
</LI>
|
|
|
|
<LI>perlmod - Hvordan man bruker moduler i perl.
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</LI>
|
|
|
|
<LI>Prøv også <CODE>perldoc -tf funksjonsnavn</CODE>!
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Bøker</H3>
|
|
|
|
<UL>
|
|
|
|
<LI>"Learning Perl" - O'Reilly & Associates - ISBN:
|
|
1-56592-284-0
|
|
</LI>
|
|
|
|
<LI>"Programming Perl" - O'Reilly & Associates - ISBN:
|
|
1-56592-149-6
|
|
</LI>
|
|
|
|
<LI>"Perl Cookbook" - O'Reilly & Associates - ISBN:
|
|
1-56592-243-3
|
|
</LI>
|
|
|
|
<LI>"Mastering Regular Expressions" - O'Reilly & Associates -
|
|
ISBN: 1-56592-257-3
|
|
</LI>
|
|
|
|
<LI>"Object Oriented Perl" - Manning Publications - ISBN:
|
|
1-88477-779-1
|
|
</LI>
|
|
|
|
</UL>
|
|
|
|
</P>
|
|
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C28'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 28: XML::Parser og XML::RSS</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>'Mine overskrifter'</H3>
|
|
|
|
Scriptet, beskrivelse av det og eksempler på bruk kan du finne på
|
|
<A HREF='http://www.webreference.com/perl/tutorial/8/'>http://www.webreference.com/perl/tutorial/8/</A>
|
|
.
|
|
|
|
<BR><TABLE CLASS="perlcode" BGCOLOR='#eeeeee' WIDTH=100% BORDER=1 CELLPADDING=5>
|
|
<TR><TD CLASS="perlcode"><FONT SIZE=-1><PRE>
|
|
|
|
#!/usr/bin/perl -w
|
|
# rss2html - converts an RSS file to HTML
|
|
# It take one argument, either a file on the local system,
|
|
# or an HTTP URL like http://slashdot.org/slashdot.rdf
|
|
# by Jonathan Eisenzopf. v1.0 19990901
|
|
# Copyright (c) 1999 internet.com Corp. All Rights Reserved.
|
|
# See http://www.webreference.com/perl for more information
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
|
|
# INCLUDES
|
|
use strict;
|
|
use XML::RSS;
|
|
use LWP::Simple;
|
|
|
|
# Declare variables
|
|
my $content;
|
|
my $file;
|
|
|
|
# MAIN
|
|
# check for command-line argument
|
|
die "Usage: rss2html.pl (<RSS file> | <URL>)\n" unless @ARGV == 1;
|
|
|
|
# get the command-line argument
|
|
my $arg = shift;
|
|
|
|
# create new instance of XML::RSS
|
|
my $rss = new XML::RSS;
|
|
|
|
# argument is a URL
|
|
if ($arg=~ /http:/i) {
|
|
$content = get($arg);
|
|
die "Could not retrieve $arg" unless $content;
|
|
# parse the RSS content
|
|
$rss->parse($content);
|
|
|
|
# argument is a file
|
|
} else {
|
|
$file = $arg;
|
|
die "File \"$file\" does't exist.\n" unless -e $file;
|
|
# parse the RSS file
|
|
$rss->parsefile($file);
|
|
}
|
|
|
|
# print the HTML channel
|
|
print_html($rss);
|
|
|
|
# SUBROUTINES
|
|
sub print_html {
|
|
my $rss = shift;
|
|
print <<HTML;
|
|
<TABLE BGCOLOR="#000000" BORDER="0" WIDTH="200"><TR><TD>
|
|
<TABLE CELLSPACING="1" CELLPADDING="4" BGCOLOR="#FFFFFF"
|
|
BORDER=0 WIDTH="100%">
|
|
<TR>
|
|
<TD VALIGN="middle" ALIGN="center" BGCOLOR="#EEEEEE"><FONT
|
|
COLOR="#000000" FACE="Arial,Helvetica"><B><A
|
|
HREF="$rss->{'channel'}->{'link'}">$rss->{'channel'}->{'title'}</A>
|
|
</B></FONT></TD></TR>
|
|
<TR><TD>
|
|
HTML
|
|
|
|
# print channel image
|
|
if ($rss->{'image'}->{'link'}) {
|
|
print <<HTML;
|
|
<CENTER>
|
|
<P><A HREF="$rss->{'image'}->{'link'}"><IMG
|
|
SRC="$rss->{'image'}->{'url'}" ALT="$rss->{'image'}->{'title'}"
|
|
BORDER="0"
|
|
HTML
|
|
print " WIDTH=\"$rss->{'image'}->{'width'}\""
|
|
if $rss->{'image'}->{'width'};
|
|
print " HEIGHT=\"$rss->{'image'}->{'height'}\""
|
|
if $rss->{'image'}->{'height'};
|
|
print "></A></CENTER><P>\n";
|
|
}
|
|
|
|
# print the channel items
|
|
foreach my $item (@{$rss->{'items'}}) {
|
|
next unless defined($item->{'title'})
|
|
&& defined($item->{'link'});
|
|
|
|
print "<LI><A HREF=\"$item->{'link'}\">".
|
|
"$item->{'title'}</A><BR>\n";
|
|
}
|
|
|
|
# if there's a textinput element
|
|
if ($rss->{'textinput'}->{'title'}) {
|
|
print <<HTML;
|
|
<FORM METHOD="GET" ACTION="$rss->{'textinput'}->{'link'}">
|
|
$rss->{'textinput'}->{'description'}<BR>
|
|
<INPUT TYPE="text" NAME="$rss->{'textinput'}->{'name'}"><BR>
|
|
<INPUT TYPE="submit" VALUE="$rss->{'textinput'}->{'title'}">
|
|
</FORM>
|
|
HTML
|
|
}
|
|
|
|
# if there's a copyright element
|
|
if ($rss->{'channel'}->{'copyright'}) {
|
|
print <<HTML;
|
|
<P><SUB>$rss->{'channel'}->{'copyright'}</SUB></P>
|
|
HTML
|
|
}
|
|
|
|
print <<HTML;
|
|
</TD>
|
|
</TR>
|
|
</TABLE>
|
|
</TD></TR></TABLE>
|
|
HTML
|
|
}
|
|
</PRE></FONT></TD></TR></TABLE><BR>
|
|
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
<A NAME='C29'><P><TABLE WIDTH=80% BORDER=0>
|
|
<TR><TH CELLPADDING=15 COLSPAN=2 BGCOLOR='#77eeff'><BR><HR SIZE=1 NOSHADE><FONT SIZE=+2>Del 29: Annet?</FONT><BR><HR SIZE=1 NOSHADE></TR>
|
|
<TR><TD WIDTH=100%>
|
|
|
|
<P CLASS='paragraph'>
|
|
<H3 CLASS='paragraph'>Så kan man spørre...</H3>
|
|
|
|
<CODE>perl -e 'print "Hva nå?\n";'</CODE>
|
|
</P>
|
|
|
|
</TD><TD WIDTH=50%></TD></TABLE>
|
|
|
|
|
|
</HTML>
|