2025-03-05 12:33:13 +01:00

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'>&Aring;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&oslash;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&aring;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&oslash;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, "&lt;$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'>&Aring;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 = &lt;PASSWD&gt;;
print $line;
# "navnsen:sEp4D.g/dg:6000:133:Etter Navnsen:/home/navnsen:/bin/false\n"
local( $/ ) = ":";
my $field = &lt;PASSWD&gt;;
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, "&lt;fil.txt" )
|| die "Kan'ke lese fila 'fil.txt': $!\n";
while ( &lt;FILE&gt; ) {
# 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, "&gt;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&oslash;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, "&lt;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>&lt;&gt;</CODE>. Om programmet ditt ikke tr noen argumenter vil
<CODE>&lt;&gt;</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 ( &lt;&gt; ) {
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 = &lt;STDIN>;
chomp($tall); # fjerne linjeskift
if ( $tall > 0 ) {
print "positivt tall\n";
elsif ($tall &lt; 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 &amp;&amp; $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>&amp;&amp;</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 &amp;&amp; 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&oslash;kker</FONT><BR><HR SIZE=1 NOSHADE></TR>
<TR><TD WIDTH=100%>
<P CLASS='paragraph'>
<H3 CLASS='paragraph'>While og Until-l&oslash;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 &lt; 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&oslash;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 &lt;= 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&aring; 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&aring; eksterne programmer!</FONT><BR><HR SIZE=1 NOSHADE></TR>
<TR><TD WIDTH=100%>
<P CLASS='paragraph'>
<H3 CLASS='paragraph'>Hva kan g&aring; 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 / >&amp;- 2>&amp;- &amp;';
# Dette kan komme fra en ekstern kilde! kanskje du
# leste inn parametere fra &lt;STDIN&gt;?
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&aring; &aring; 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&aelig;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&oslash;mte v&aring;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 = &lt;&gt; ) {
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&aring;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( &lt;&gt; ) {
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&oslash;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 = &lt;DATA&gt; # 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__
&lt;HTML&gt;
&lt;HEAD&gt;&lt;TITLE&gt;CGI_Lite-test&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;H1&gt;Hei, $NAVN&lt;/H1&gt;
Du er $ALDER gammel, har jeg hørt!
&lt;HR&gt;
&lt;FORM METHOD="POST" ACTION="$SCRIPT_URL"&gt;
Navn: &lt;INPUT TYPE="text" NAME="NAVN" VALUE="$NAVN"&gt;&lt;BR&gt;
Alder: &lt;INPUT TYPE="text" NAME="ALDER" VALUE="$ALDER"&gt;&lt;BR&gt;
&lt;INPUT TYPE="submit"&gt;
&lt;/FORM&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;
</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&oslash;ker</H3>
<UL>
<LI>"Learning Perl" - O'Reilly &amp; Associates - ISBN:
1-56592-284-0
</LI>
<LI>"Programming Perl" - O'Reilly &amp; Associates - ISBN:
1-56592-149-6
</LI>
<LI>"Perl Cookbook" - O'Reilly &amp; Associates - ISBN:
1-56592-243-3
</LI>
<LI>"Mastering Regular Expressions" - O'Reilly &amp; 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 (&lt;RSS file> | &lt;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 &lt;&lt;HTML;
&lt;TABLE BGCOLOR="#000000" BORDER="0" WIDTH="200">&lt;TR>&lt;TD>
&lt;TABLE CELLSPACING="1" CELLPADDING="4" BGCOLOR="#FFFFFF"
BORDER=0 WIDTH="100%">
&lt;TR>
&lt;TD VALIGN="middle" ALIGN="center" BGCOLOR="#EEEEEE">&lt;FONT
COLOR="#000000" FACE="Arial,Helvetica">&lt;B>&lt;A
HREF="$rss->{'channel'}->{'link'}">$rss->{'channel'}->{'title'}&lt;/A>
&lt;/B>&lt;/FONT>&lt;/TD>&lt;/TR>
&lt;TR>&lt;TD>
HTML
# print channel image
if ($rss->{'image'}->{'link'}) {
print &lt;&lt;HTML;
&lt;CENTER>
&lt;P>&lt;A HREF="$rss->{'image'}->{'link'}">&lt;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 ">&lt;/A>&lt;/CENTER>&lt;P>\n";
}
# print the channel items
foreach my $item (@{$rss->{'items'}}) {
next unless defined($item->{'title'})
&amp;&amp; defined($item->{'link'});
print "&lt;LI>&lt;A HREF=\"$item->{'link'}\">".
"$item->{'title'}&lt;/A>&lt;BR>\n";
}
# if there's a textinput element
if ($rss->{'textinput'}->{'title'}) {
print &lt;&lt;HTML;
&lt;FORM METHOD="GET" ACTION="$rss->{'textinput'}->{'link'}">
$rss->{'textinput'}->{'description'}&lt;BR>
&lt;INPUT TYPE="text" NAME="$rss->{'textinput'}->{'name'}">&lt;BR>
&lt;INPUT TYPE="submit" VALUE="$rss->{'textinput'}->{'title'}">
&lt;/FORM>
HTML
}
# if there's a copyright element
if ($rss->{'channel'}->{'copyright'}) {
print &lt;&lt;HTML;
&lt;P>&lt;SUB>$rss->{'channel'}->{'copyright'}&lt;/SUB>&lt;/P>
HTML
}
print &lt;&lt;HTML;
&lt;/TD>
&lt;/TR>
&lt;/TABLE>
&lt;/TD>&lt;/TR>&lt;/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&aring; kan man sp&oslash;rre...</H3>
<CODE>perl -e 'print "Hva nå?\n";'</CODE>
</P>
</TD><TD WIDTH=50%></TD></TABLE>
</HTML>