ein Kapitel zurück                                           ein Kapitel weiter

In unserem Kaptitel zuvor haben sie gesehen wie es möglich ist mit Hilfe der Standardvariablen @_ Parameter die wir an eine Funktion übergeben weiterverarbeiten können. Was aber jetzt wenn wir folgendes von unserer Funktion berechnen lassen wollen.......

multipliziere($werta, $wertb);

Dafür gibt es in Perl eine weitere Standardvariable für Funktionen. Nämlich....

$_[INDEX];

Der erste Parameter sieht also so aus.......

$_[0];

Der zweite..... $_[1] der dritte....... $_[2] usw.
Folglich können wir unsere neue Standardvariable für Funktionen wie folgt einsetzten........

#!/usr/bin/perl -w

sub mehr_parameter
 {
  print "1.Parameter : " . $_[0] . "\n";
  print "2.Parameter : " . $_[1] . "\n";
  print "3.Parameter : " . $_[2]. "\n";
 }

$var=666;
$name=0;

print "Bitte geben sie Ihren Namen ein : ";
chomp ($name = <STDIN>);

mehr_parameter($var, $name, 999);
print "\n";
mehr_parameter($name, "Hallo", "Welt");


Bei Array, Hashes und Listen wird dies nun wieder nicht funktionieren. Das Programm wird zwar ablaufen aber durch die Parameterübergabe $_[0] werden die einzelnen Argumente eines Arrays gebrochen. Damit würde nur das erste Argument eine Arrays ausgegeben werden. Hier ein Beispiel dazu.......

#!/usr/bin/perl -w

sub lese_array
 {
  @tmp = $_[0];
  print "@tmp\n";
 }

@tmp=0;
@array = ("Feuer", "Eis", "Flamme", "Ball");

lese_array(@array);


Hier wird nur das Wort "Feuer" ausgegeben. Sie können gerne in der Funktion eingeben....

print $_[1] , "\n";

Somit wird "Feuer" und "Eis" ausgeben. Was können wir also tun damit ein Array, Hashes oder Listen nicht gebrochen werde?
In diesem Fall sicherlich die Standardvariable @_ aber sobald wir mehrer Parameter übergeben und vor allem Unterschiedliche funktioniert dies auch nicht so.....

#!/usr/bin/perl -w

sub lese_verschiedenes
 {
  @tmp = @_ ;
  print "@tmp\n";
 }

@tmp=0;
@array = ("Feuer", "Eis", "Flamme", "Ball");
$var=99;
%hash = ("Name" => "user",
                "Vorname" => "superuser");

lese_verschiedenes(@array, $var, %hash);


An diesem Beispiel können sie sehen werden alle drei Parameter in die Standardvariable @_ gelegt und sind somit nicht mehr voneinander zu unterscheiden.

Wir benötigen also etwas womit sie so etwas wie die Adresse unserer Variablen an den Funktionen übergeben kann. Ein Schelm wer da jetzt an Zeigern denkt ;)
Und doch haben sie Recht sollten sie an dies Gedacht haben. In Perl gibt es auch, wir nennen sie jetzt Referenzen, so etwas wie die Zeiger. Aber keine Angst, in Perl ist es nicht möglich auf irgendeine Adresse zu zeigen und damit ein Chaos zu verursachen wie etwa in C. Referenzen in Perl werden nur verwendet um auf Variablen zu verweisen.
Referenzen in Perl werden einfache dem Array oder dem Hash mit einem '\' (Backslash) vorangestellt. Dies wollen wir wieder Anhand eines Beispiels demonstrieren.......

#!/usr/bin/perl -w

sub lese_array
 {
  $tmp = $_[0];
  print "@{$tmp}" , "\n";
 }

$tmp=0;
@array = ("Feuer", "Eis", "Flamme", "Ball");

lese_array(\@array);


Machen sie sich jetzt noch keinen Gedanken zu dem Syntax. Wir kommen noch zu den Referenzen. Wichtig ist jetzt nur das sie wissen wie man Arrays, Listen und Hash an eine Funktion (Unterprogramm) übergeben kann.
Hier nun ein Beispiel wie schon oben wo mehrere Fälle aufeinandertreffen......

#!/usr/bin/perl -w

sub lese_verschiedenes
 {
  $tmp = $_[0] ;
  print "@{$tmp}\n";
  $tmp = $_[1];
  print $tmp , "\n";
  $tmp = $_[2];
  print %{$tmp} , "\n";
 }

$tmp=0;
@array = ("Feuer", "Eis", "Flamme", "Ball");
$var=99;
%hash = ("Name" => "user",
                "Vorname" => "superuser");

lese_verschiedenes(\@array, $var, \%hash);


Was uns an den Funktionen bisher gestört hat ist das wir immer Globale Variablen eingesetzt haben. Das sind Variablen die für das gesamte Programm sichtbar sind. Wie im folgendem Beispiel.....

#!/usr/bin/perl -w

sub global
 {
   print $var , "\n";
 }

$var=99;

print $var , "\n";
global();


Hier wird zweimal 99 ausgeben. Nun was ist aber wenn wir in der Funktion die Zahl verändern, obwohl wir den Wert noch für weiteren Berechnungen benötigen? Beipspiel.........

#!/usr/bin/perl -w

sub global
 {
   $var*=2;
   print $var , "\n";
 }

$var=99;

print $var , "\n";
global();
printf "Hier präsentieren wir den Wert 99 : " . $var . "\n";


Tja das war wohl nichts mit dem Wert 99. Damit eine Variable nur für Ihre Funktion gültig ist benötigen wir das Schlüsselwort my. Hier nun unser Beispiel mit my.........

#!/usr/bin/perl -w

sub global
 {
  my $var= $_[0];     #lokale Variable
  $var*=2;
  print $var , "\n";
 }

$var=99;

print $var , "\n";
global($var);
printf "Hier präsentieren wir den Wert 99 : " . $var . "\n";


Natürlich könnten sie auch in der Hauptfunktion das Wort my vor $var stellen und in der Funktion global entfernen. Es würde genauso funktionieren. Natürlich haben wir in diesem Beispiel die Variable $var als Parameter an unsere Funktion global übergeben. Denn durch die Definition my $var haben wir zwar 2 identisch lautetende Variablen, aber belegen diese beiden einen völlig anderen Adressplatz im Speicher.

Eine weitere Möglichkeit ein Funktion lokal zu definieren wäre das Schlüsselwort local. Mit diesem Schlüsselwort ist es möglich das eine Variable in der Funktion als lokal definiert wird aber für andere Unterfunktionen, damit sind weitere Funktionen gemeint, global bzw. sichtbar bleiben. Einfaches Beispiel.......

#!/usr/bin/perl -w

sub func1
 {
  local $var= $_[0];      #$var ist local aber für func2 sichtbar
  $var*=2;
  print $var , "\n";
  func2();
 }

sub func2
 {
  $var*=2;        #ist local $var von func1
  print $var , "\n";
 }

$var=99;

print $var , "\n";
func1($var);
printf "Hier präsentieren wir den Wert 99 : " . $var . "\n";


Hier haben wir durch das Schlüsselwort local die Variable $var als lokal definiert. Diese ist aber durch das Schlüsselwort local von der Funktion func2 sowie für weitere Unterfunktionen sichtbar. Nur nicht für die Hauptfunktion. Was uns die Ausgabe auch bestätigen wird.

Die Parameterübergabe in @_ kann auch durch Iteratives zerstörendes Auslesen der Parameterliste mittels shift geschehen.....

#!/usr/bin/perl -w

sub func{
   my $var1=shift;
   my $var2=shift;
   my $var3=shift;
   my $var4=shift;

    return $var1+$var2+$var3+$var4;
}

@array = (10,30,13,11);

$ergebnis=func(@array);
print $ergebnis , "\n";


Mit dieser Methode wird jeder Wert in Array pro shift-Aufruf an eine Variable übergeben. Der Inhalt von @_ wird dabei aber Zerstört.

Um in Perl wie in C statische Variablen zu reallieren, können sie sich mit einem BEGIN-Block behelfen....

#!/usr/bin/perl -w

BEGIN{
   my $stat=0; #Statische Variable
    sub func{
       print $stat++ ,"\n";
     }
}

 foreach(0..10){
  func(); #Funktionsaufruf
}


Die Funktion selbst befindet sich dabei im BEGIN-Block. Achja statische Variablen sind Variable die Ihren Wert nach dem Beenden der Funktion behalten und man beim nächsten Funktions auf diese Statische Variablen zugreifen kann. Besser noch als in C können auf diese Variable gleich mehrere Funktionen auf einmal zugreifen......

#!/usr/bin/perl -w

BEGIN{
  my $stat=0; #Statische Variable
    sub func{
       print $stat++ ,"\n";
    }
    sub func2{
      print $stat * $stat ,"\n";
    }
}

foreach(0..10){
    func(); func2();  #Funktionsaufruf
}


ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf