Perl Language
Unterprogramme
Suche…
Bemerkungen
Unterprogramme erhalten ihre Argumente in eine magische Variable namens @_
. Es muss zwar nicht entpackt werden, es wird jedoch empfohlen, da es die Lesbarkeit @_
und versehentliche Änderungen verhindert, da Argumente von @_
als Referenz übergeben werden (können geändert werden).
Unterprogramme erstellen
Unterprogramme werden erstellt, indem das Schlüsselwort sub
gefolgt von einem Bezeichner und einem in geschweiften Klammern eingeschlossenen Codeblock verwendet wird.
Sie können auf die Argumente zugreifen, indem Sie die spezielle Variable @_
, die alle Argumente als Array enthält.
sub function_name {
my ($arg1, $arg2, @more_args) = @_;
# ...
}
Da die Funktion shift
bei Verwendung in einer Subroutine standardmäßig auf @_
verschoben wird, ist es ein übliches Muster, die Argumente am Anfang einer Subroutine nacheinander in lokale Variablen zu extrahieren:
sub function_name {
my $arg1 = shift;
my $arg2 = shift;
my @more_args = @_;
# ...
}
# emulate named parameters (instead of positional)
sub function_name {
my %args = (arg1 => 'default', @_);
my $arg1 = delete $args{arg1};
my $arg2 = delete $args{arg2};
# ...
}
sub {
my $arg1 = shift;
# ...
}->($arg);
Alternativ kann die experimentelle Funktion "signatures"
verwendet werden, um Parameter zu entpacken, die als Wert übergeben werden ( nicht als Referenz).
use feature "signatures";
sub function_name($arg1, $arg2, @more_args) {
# ...
}
Für die Parameter können Standardwerte verwendet werden.
use feature "signatures";
sub function_name($arg1=1, $arg2=2) {
# ...
}
Sie können einen beliebigen Ausdruck verwenden, um einem Parameter einen Standardwert zuzuweisen - einschließlich anderer Parameter.
sub function_name($arg1=1, $arg2=$arg1+1) {
# ...
}
Beachten Sie, dass Sie keine Parameter referenzieren können, die nach dem aktuellen Parameter definiert sind. Der folgende Code funktioniert daher nicht ganz wie erwartet.
sub function_name($arg1=$arg2, $arg2=1) {
print $arg1; # => <nothing>
print $arg2; # => 1
}
Unterprogrammargumente werden als Referenz übergeben (außer bei Unterschriften).
Unterprogrammargumente in Perl werden als Referenz übergeben, sofern sie nicht in der Signatur enthalten sind. Dies bedeutet, dass die Mitglieder des @_
Arrays im Sub nur Aliase für die eigentlichen Argumente sind. Im folgenden Beispiel wird $text
im Hauptprogramm nach dem Unterprogrammaufruf geändert, da $_[0]
im Unterprogramm tatsächlich nur ein anderer Name für dieselbe Variable ist. Beim zweiten Aufruf wird ein Fehler ausgegeben, da ein Zeichenfolgenliteral keine Variable ist und daher nicht geändert werden kann.
use feature 'say';
sub edit {
$_[0] =~ s/world/sub/;
}
my $text = "Hello, world!";
edit($text);
say $text; # Hello, sub!
edit("Hello, world!"); # Error: Modification of a read-only value attempted
Um zu vermeiden, dass die Variablen Ihres Aufrufers @_
, ist es wichtig, @_
in lokale Variablen ( my ...
) zu kopieren, wie unter "Erstellen von Unterprogrammen" beschrieben.
Unterprogramme
Unterprogramme halten Code. Wenn nicht anders angegeben, sind sie global definiert.
# Functions do not (have to) specify their argument list
sub returns_one {
# Functions return the value of the last expression by default
# The return keyword here is unnecessary, but helps readability.
return 1;
}
# Its arguments are available in @_, however
sub sum {
my $ret = 0;
for my $value (@_) {
$ret += $value
}
return $ret;
}
# Perl makes an effort to make parens around argument list optional
say sum 1..3; # 6
# If you treat functions as variables, the & sigil is mandatory.
say defined ∑ # 1
Einige eingebaute Elemente wie print
oder say
sind Schlüsselwörter und keine Funktionen. Daher ist &say
definiert. Es bedeutet auch, dass Sie sie definieren können, aber Sie müssen den Paketnamen angeben, um sie tatsächlich aufrufen zu können
# This defines the function under the default package, 'main'
sub say {
# This is instead the say keyword
say "I say, @_";
}
# ...so you can call it like this:
main::say('wow'); # I say, wow.
Seit Perl 5.18 können Sie auch nicht globale Funktionen verwenden:
use feature 'lexical_subs';
my $value;
{
# Nasty code ahead
my sub prod {
my $ret = 1;
$ret *= $_ for @_;
$ret;
}
$value = prod 1..6; # 720
say defined ∏ # 1
}
say defined ∏ # 0
Seit 5.20 können Sie auch Parameter benennen.
use feature 'signatures';
sub greet($name) {
say "Hello, $name";
}
Dies sollte nicht mit Prototypen verwechselt werden. In Perl müssen Sie Funktionen definieren, die sich wie eingebaute Funktionen verhalten. Funktionsprototypen müssen sichtbar sein bei der Kompilierung und ihre Auswirkungen können durch die Angabe des ignoriert &
sigil. Prototypen gelten im Allgemeinen als fortschrittliche Funktion, die am besten mit großer Sorgfalt eingesetzt wird.
# This prototype makes it a compilation error to call this function with anything
# that isn't an array. Additionally, arrays are automatically turned into arrayrefs
sub receives_arrayrefs(\@\@) {
my $x = shift;
my $y = shift;
}
my @a = (1..3);
my @b = (1..4);
receives_arrayrefs(@a, @b); # okay, $x = \@a, $y = \@b, @_ = ();
receives_arrayrefs(\@a, \@b); # compilation error, "Type … must be array …"
BEGIN { receives_arrayrefs(\@a, \@b); }
# Specify the sigil to ignore the prototypes.
&receives_arrayrefs(\@a, \@b); # okay, $x = \@a, $y = \@b, @_ = ();
&receives_arrayrefs(@a, @b); # ok, but $x = 1, $y = 2, @_ = (3,1,2,3,4);