EMZETT.
Login

Kurz: Argumente landen im Array @_. Der Rückgabewert ist der letzte ausgewertete Ausdruck (oder return).

Teil des Kurses Perl

Kapitel 5 von 11 im Kurs Perl. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Subroutinen definieren

Argumente landen im Array @_. Der Rückgabewert ist der letzte ausgewertete Ausdruck (oder return).

use strict; use warnings;
 
sub gruss {
    my ($name, $anrede) = @_;
    $anrede //= "Hallo";
    return "$anrede, $name!";
}
 
sub summe {
    my $s = 0;
    $s += $_ for @_;          # beliebig viele Argumente
    return $s;
}
 
sub minmax {
    my @sortiert = sort { $a <=> $b } @_;
    return ($sortiert[0], $sortiert[-1]);       # mehrere Werte
}
 
sub optionen {
    my (%opt) = (farbe => "blau", groesse => 10, @_);   # benannte Argumente mit Standardwerten
    return join(", ", map { "$_=$opt{$_}" } sort keys %opt);
}
 
print gruss("Mia"), "\n";
print gruss("Tom", "Hi"), "\n";
print summe(1, 2, 3, 4), "\n";
my ($klein, $gross) = minmax(5, 2, 9, 1);
print "$klein $gross\n";
print optionen(groesse => 20, rahmen => "ja"), "\n";
print "Argumente: ", scalar(@{[ 1, 2, 3 ]}), "\n";

Ausgabe:

Hallo, Mia!
Hi, Tom!
10
1 9
farbe=blau, groesse=20, rahmen=ja
Argumente: 3

Hinweis

my ($a, $b) = @_; kopiert die Argumente in lokale Variablen. Greife nicht direkt auf $_[0] zu, außer du willst bewusst das Original ändern (Perl übergibt Aliase).

Seit Perl 5.36 gibt es Signaturen:

use v5.36;                       # aktiviert strict, warnings, say und Signaturen
sub addiere($x, $y = 10) { return $x + $y }
say addiere(1);
say addiere(1, 2);
sub ersten_und_rest($erster, @rest) { return "$erster | @rest" }
say ersten_und_rest(qw(a b c));
sub mit_hash($name, %opt) { "$name: " . join(",", map {"$_=$opt{$_}"} sort keys %opt) }
say mit_hash("x", b => 2, a => 1);

Ausgabe:

11
3
a | b c
x: a=1,b=2

say ist wie print, hängt aber automatisch einen Zeilenumbruch an.

Kontext: wantarray

Eine Funktion kann prüfen, ob sie in Listen- oder Skalarkontext aufgerufen wird:

use v5.36;
sub kontext {
    return wantarray ? "Liste" : defined(wantarray) ? "Skalar" : "void";
}
my @l = kontext();
my $s = kontext();
kontext();
say "$l[0] $s";

Ausgabe:

Liste Skalar

Referenzen auf Funktionen und Closures

use v5.36;
my $quadrat = sub ($x) { $x * $x };          # anonyme Funktion
say $quadrat->(7);
 
sub zaehler_erzeugen($start = 0) {
    my $n = $start;
    return {
        plus  => sub { ++$n },
        minus => sub { --$n },
        wert  => sub { $n },
    };
}
my $z = zaehler_erzeugen(10);
$z->{plus}->() for 1..3;
$z->{minus}->();
say $z->{wert}->();
 
sub wende_an($f, @liste) { map { $f->($_) } @liste }
say join ",", wende_an(sub ($x) { $x * 10 }, 1, 2, 3);
my %dispatch = (hallo => sub { "Hallo!" }, tschuess => sub { "Tschüss!" });
say $dispatch{hallo}->();
my $ref = \&wende_an;
say ref($ref);

Ausgabe:

49
12
10,20,30
Hallo!
CODE

Closures merken sich die Variablen ihrer Umgebung ($n oben).

Rekursion und Variablen-Gültigkeit

use v5.36;
sub fakultaet($n) { $n <= 1 ? 1 : $n * fakultaet($n - 1) }
sub fib($n) { $n < 2 ? $n : fib($n - 1) + fib($n - 2) }
say fakultaet(15);
say join " ", map { fib($_) } 0..12;
 
our $global = "global";           # Paketvariable
my $lexikalisch = "außen";
sub test {
    my $lexikalisch = "innen";    # verdeckt die äußere
    return "$lexikalisch $global";
}
say test();
say $lexikalisch;
{
    local $global = "lokal überschrieben";
    say test();
}
say test();

Ausgabe:

1307674368000
0 1 1 2 3 5 8 13 21 34 55 89 144
innen global
außen
innen lokal überschrieben
innen global

Nutze my (lexikalisch, im Block gültig). our deklariert Paketvariablen, local überschreibt sie temporär (selten nötig).

Merke

  • Argumente in @_, kopiere sie mit my (...) = @_;
  • return ist optional, mehrere Werte als Liste
  • Signaturen (sub f($x, $y = 1)) und say mit use v5.36;
  • Anonyme Subs sub {...}, Referenzen \&f, Aufruf $ref->(...)
  • wantarray erkennt den Kontext; Closures merken sich Variablen

Übungsaufgabe

Schreibe eine Funktion statistik(@zahlen), die Summe, Mittelwert und Maximum als Hash zurückgibt.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Kontrollstrukturen

Weiter: Reguläre Ausdrücke

Alle Kapitel: Perl im Überblick