Till Startsidan
JavaScript.nu / Perl-kurs / Returv�rden och argument

L�R DIG ATT PROGRAMMERA PERL
Returv�rden och argument

Eftersom subrutiner �r s� extremt viktiga och jag inte vill att du gl�mmer vad du tidigare l�rt dig om subrutiner ska vi nu �ter g� tillbaka till det. Vi ska dock g� ett steg l�ngre nu. Vi ska l�ra oss hur man skickar med argument till subrutinen vid anropet och hur man tar tillvara dess returv�rde. L�ter det komplicerat? Inte alls, v�rt lilla exempel nedan visar hur l�tt detta �r:
#!/usr/bin/perl
print "Content-type:text/html\n\n";

sub geNamn
{
$fornamn = $_[0];		#Lagrar f�rsta argumentet till funktionen
$efternamn = $_[1];	#Lagrar andra argumentet till funktionen

return "$fornamn $efternamn"; 	#Nu returneras en str�ng. V�rdet lagras i "$helaNamnet" nedan
print "Detta �r helt on�digt!";	#Vid return (ovan) avslutas subrutinen(!!!),
				#s� denna rad kommer att ignoreras av scriptet.
				#Vi skulle med andra ord ha kunnat strunta i detta helt.
}

$helaNamnet=&geNamn('Adam','Svensson');	#H�r anropar vi funktionen "geNamn".
					#Som argument skickar vi "Adam" och "Svensson"
					#$helaNamnet kommer nu f� v�rdet "Adam Svensson",
					#eftersom geNamn returnerar detta.

print "'helaNamnet' inneh�ller nu: $helaNamnet";	#Detta skriver vi ut bara f�r att se vad som h�nt

Utmatning:
'helaNamnet' inneh�ller nu: Adam Svensson
Vad �r nu nytt i scriptet?
Jo, f�rst har vi en subrutin som vi kallar geNamn. Denna anropas en g�ng av scriptet vid raden $helaNamnet=&geNamn('Adam','Svensson');.
Till skillnad mot vad vi tidigare gjort s� anropar vi inte subrutinen med endast &geNamn;, utan den h�r g�ngen skickar vi �ven med tv� argument: Adam och Svensson
I sj�lva subrutinen kommer vi �t dessa genom variablerna $_[0] samt $_[1]. Observera att det f�rsta argumentet �r 0 och det andra �r 1.
V�rdena vi skickar kan ses som en array som skickas. Vi skulle med andra ord ha kunnat �ndra denna rad...
$helaNamnet=&geNamn('Adam','Svensson');
...mot dessa rader...
@namnen=('Adam','Svensson');
$helaNamnet=&geNamn(@namnen);

Av detta kan vi allts� dra slutsatsen att �ven subrutinen hanterar argumenten som en array. Dvs, man kan anv�nda funktioner p� argumenten precis som om det vore en vanlig array. Observera att vi d� ist�llet f�r $_[X] m�ste anv�nda @_, eftersom detta �r en array. Exempel p� vad man kan g�ra:

@_=sort(@_);		#Sorterar arrayen i teckenordning
@_=reverse(@_);		#V�nder p� arrayen. Sista v�rdet kommer f�rst, f�rsta kommer sist etc.
$sistaIndexet=$#_;	#Sista indexet i arrayen lagras (@_)
Ut�ver dessa funktioner kan man utf�ra alla andra operationer p� @_ som man kan g�ra p� en vanlig array man skapar p� vanligt vis.

Observera att man inte n�dv�ndigtvis beh�ver skicka alla argumenten som vanliga str�ngar. Om man vill kan man skicka argumenten genom en array eller om man s� vill genom arrayer och str�ngar. Nedan visas ett korrekt s�tt att anropa en funktion med ett flertal v�rden:

#!/usr/bin/perl
print "Content-type:text/html\n\n";
sub vilkaVardenSkickas
{
	foreach $ettVarde (@_)
	{
	print "$ettVarde ";
	}
}

@nagraVarden=("Gustav","sade:");
@nagraNyaVarden=("Hejsan","hoppsan");
$ettTillVarde="Sedan var han tyst.";

print "Dessa argument har skickats till funktionen (subrutinen):\n";	#Detta skriver vi ut bara f�r att se vad som h�nt
&vilkaVardenSkickas(@nagraVarden, @nagraNyaVarden, "\n", $ettTillVarde);

Utmatning:
Dessa argument har skickats till funktionen (subrutinen):
Gustav sade: Hejsan hoppsan
 Sedan var han tyst.
Observera att jag ist�llet f�r raden...
&vilkaVardenSkickas(@nagraVarden, @nagraNyaVarden, "\n", $ettTillVarde);
...Lika bra skulle ha kunnat haft denna rad...
&vilkaVardenSkickas("Gustav", "sade:", "Hejsan", "hoppsan", "\n", "Sedan var han tyst.");

Om du undrar varf�r den sista raden blivit inskjuten med ett mellanslag s� beror detta helt logiskt p� att funktionen vilkaVardenSkickas skriver ut alla argumenten ett och ett, f�ljt av ett mellanslag mellan varje utmatning. N�r d� argumentet "\n" ska skrivas ut skriver funktionen ut "\n ", dvs. ett radbyte f�ljt av ett mellanslag, vilket allts� g�r s� att den sista raden ("Sedan var han tyst.") blir inskjuten.

Vill du s� kan du givetvis ha l�nga str�ngar eller stora arrayer direkt som returv�rden. H�r �r ett exempel p� hur man kan anv�nda sig av funktioner p� ett smart s�tt:

#!/usr/bin/perl
print "Content-type:text/html\n\n";
@medlemmar=("Nisse;man\@power.se","Sven;sven\@svensson.se","Bert;bert\@bertilsson.com");

sub fixaTabell
{
return "<TR><TD>$_[0]</TD><TD>$_[1]</TD></TR>\n";
}

print "<TABLE>\n";
foreach $par (@medlemmar)
{
print &fixaTabell(split(/;/,$par));		#split g�r str�ngen "a;b" till en array inneh�llande 2 v�rden: a och b
}
print "</TABLE>";

Utmatning:
<TABLE>
<TR><TD>Nisse</TD><TD>man@power.se</TD></TR>
<TR><TD>Sven</TD><TD>sven@svensson.se</TD></TR>
<TR><TD>Bert</TD><TD>bert@bertilsson.com</TD></TR>
</TABLE>
Det h�r scriptet kan vara sv�rt att f�rst� sig p� till en b�rjan, fast kollar du n�rmare s� �r allt saker vi redan l�rt oss under denna kurs.
F�r att du helt och h�llet ska f�rst� vad som h�nt beskriver jag nedan vad som sker steg f�r steg:
Det f�rsta scriptet g�r �r att det skriver ut <TABLE> och en radbrytning. S� v�l allt lugnt. Efter detta kommer foreach $par (@medlemmar), som �r en loop som f�r oss k�r tre g�nger (eftersom arrayen @medlemmar har tre v�rden). Under varje k�rning f�r $par v�rdet som finns i varje index i @medlemmar.
F�rsta g�ngen loopen k�rs blir v�rdet allts� Nisse;man@power.se
Raden print &fixaTabell(split(/;/,$par)); kan kanske vara sv�r att f�rst� sig p�. Det den g�r �r exakt samma sak som dessa rader:
@tempArray=split(/;/,$par);		#@tempArray inneh�ller nu tv� f�lt, det ena med namnet p� personen och det andra med hans/hennes email
$tempStrang=&fixaTabell(@tempArray);	#Namnet och emailen skickas som argument till funktionen fixaTabell. Returv�rdet fr�n fixaTabell lagras i $tempStrang
print "$tempStrang";		#$tempStrang skrivs ut
Som du s�kert f�rst�r �r det mycket l�ttare att skriva allt p� en rad, fast � andra sidan, tycker du det �r l�ttare att f�rst� vad som h�nder om du anv�nder dig av tre rader kanske det �r att f�redra.
L�t oss nu g� vidare i scriptet:
fixaTabell f�r allts� tv� argument (@tempArray inneh�ller tv� v�rden), dessa l�ses av i funktionen med denna rad:
return "<TR><TD>$_[0]</TD><TD>$_[1]</TD></TR>\n";

L�gg m�rke till att raden b�rjar med return. Detta betyder att hela str�ngen som kommer efter return kommer att skickas tillbaka som returv�rde och lagras i $tempStrang (eller som det var i originalexemplet, det skrivs ut p� direkten).

En sak som kan vara bra att k�nna till �r att man kan returnera mer �n bara en rad. Hade jag velat hade jag kunnat �ndra denna rad...
return "<TR><TD>$_[0]</TD><TD>$_[1]</TD></TR>\n";
...mot dessa rader...

return <<"STOPHTML";
 <TR>
  <TD>$_[0]</TD>
  <TD>$_[1]</TD>
 </TR>
STOPHTML
Observera dock att utmatning d� ocks� inneh�ller radbrytningarna som finns i det sistvisade exemplet.
Bra att veta:
N�r du vill skriva ut flera rader direkt till sk�rmen, anv�nd d�:
print <<STOPHTML;
Hejsan hej.
Hej igen
STOPHTML
N�r du vill returnera flera rader, anv�nd d�:
return <<"STOPHTML";
Hejsan hej.
Hej igen
STOPHTML
Om du g�r fel och anv�nder citationstecken d�r du inte ska det eller inte anv�nder dem d�r du egentligen ska anv�nda dem s� f�r du fel. Var noga med detta.
(texten STOPHTML kan givetvis bytas ut mot vad helst du �nskar)

[Perl guiden] - [Till kapitel 10]






Copyright © Omid Rouhani 1997-2022; Alla r�ttigheter reserverade.
Guider: [ HTML guide ] - [ JavaScript guide ] - [ DHTML guide ] - [ Perl guide ] - [ Sitemap ]