Perl - podprogramy
Podprogram lub funkcja Perla to grupa instrukcji, które razem wykonują zadanie. Możesz podzielić swój kod na oddzielne podprogramy. To, jak podzielisz swój kod na różne podprogramy, zależy od Ciebie, ale logicznie jest to zwykle taki podział, że każda funkcja wykonuje określone zadanie.
Perl używa zamiennie terminów podprogram, metoda i funkcja.
Zdefiniuj i wywołaj podprogram
Ogólna postać definicji podprogramu w języku programowania Perl jest następująca -
sub subroutine_name {
body of the subroutine
}
Typowy sposób wywoływania tego podprogramu Perl jest następujący:
subroutine_name( list of arguments );
W wersjach Perla wcześniejszych niż 5.0, składnia wywoływania podprogramów była nieco inna, jak pokazano poniżej. To nadal działa w najnowszych wersjach Perla, ale nie jest zalecane, ponieważ omija prototypy podprogramów.
&subroutine_name( list of arguments );
Spójrzmy na poniższy przykład, który definiuje prostą funkcję, a następnie ją wywołaj. Ponieważ Perl kompiluje program przed jego wykonaniem, nie ma znaczenia, gdzie zadeklarujesz swój podprogram.
#!/usr/bin/perl
# Function definition
sub Hello {
print "Hello, World!\n";
}
# Function call
Hello();
Kiedy powyższy program jest wykonywany, daje następujący wynik -
Hello, World!
Przekazywanie argumentów do podprogramu
Możesz przekazać różne argumenty do podprogramu, tak jak robisz to w każdym innym języku programowania, i można je uzyskać wewnątrz funkcji za pomocą specjalnej tablicy @_. Zatem pierwszy argument funkcji znajduje się w$_[0], the second is in $_ [1] i tak dalej.
Możesz przekazywać tablice i skróty jako argumenty, jak każdy skalar, ale przekazanie więcej niż jednej tablicy lub skrótu zwykle powoduje utratę oddzielnych tożsamości. Dlatego użyjemy referencji (wyjaśnionych w następnym rozdziale) do przekazania dowolnej tablicy lub skrótu.
Wypróbujmy następujący przykład, który pobiera listę liczb, a następnie wyświetla ich średnią -
#!/usr/bin/perl
# Function definition
sub Average {
# get total number of arguments passed.
$n = scalar(@_); $sum = 0;
foreach $item (@_) { $sum += $item; } $average = $sum / $n;
print "Average for the given numbers : $average\n";
}
# Function call
Average(10, 20, 30);
Kiedy powyższy program jest wykonywany, daje następujący wynik -
Average for the given numbers : 20
Przekazywanie list do podprogramów
Ponieważ zmienna @_ jest tablicą, może służyć do dostarczania list do podprogramu. Jednak ze względu na sposób, w jaki Perl akceptuje i analizuje listy i tablice, wyodrębnienie poszczególnych elementów z @_ może być trudne. Jeśli musisz przekazać listę wraz z innymi argumentami skalarnymi, utwórz listę jako ostatni argument, jak pokazano poniżej -
#!/usr/bin/perl
# Function definition
sub PrintList {
my @list = @_;
print "Given list is @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);
# Function call with list parameter
PrintList($a, @b);
Kiedy powyższy program jest wykonywany, daje następujący wynik -
Given list is 10 1 2 3 4
Przekazywanie skrótów do podprogramów
Kiedy podasz hash do podprogramu lub operatora, który akceptuje listę, to hash jest automatycznie tłumaczony na listę par klucz / wartość. Na przykład -
#!/usr/bin/perl
# Function definition
sub PrintHash {
my (%hash) = @_;
foreach my $key ( keys %hash ) {
my $value = $hash{$key}; print "$key : $value\n";
}
}
%hash = ('name' => 'Tom', 'age' => 19);
# Function call with hash parameter
PrintHash(%hash);
Kiedy powyższy program jest wykonywany, daje następujący wynik -
name : Tom
age : 19
Zwracanie wartości z podprogramu
Możesz zwrócić wartość z podprogramu, tak jak w każdym innym języku programowania. Jeśli nie zwracasz wartości z podprogramu, wówczas wszelkie obliczenia, które są ostatnio wykonywane w podprogramie, są automatycznie również wartością zwracaną.
Możesz zwracać tablice i skróty z podprogramu jak każdy skalar, ale zwrócenie więcej niż jednej tablicy lub skrótu zwykle powoduje utratę oddzielnych tożsamości. Więc użyjemy referencji (wyjaśnionych w następnym rozdziale), aby zwrócić dowolną tablicę lub hash z funkcji.
Wypróbujmy następujący przykład, który pobiera listę liczb, a następnie zwraca ich średnią -
#!/usr/bin/perl
# Function definition
sub Average {
# get total number of arguments passed.
$n = scalar(@_);
$sum = 0; foreach $item (@_) {
$sum += $item;
}
$average = $sum / $n; return $average;
}
# Function call
$num = Average(10, 20, 30); print "Average for the given numbers : $num\n";
Kiedy powyższy program jest wykonywany, daje następujący wynik -
Average for the given numbers : 20
Zmienne prywatne w podprogramie
Domyślnie wszystkie zmienne w Perlu są zmiennymi globalnymi, co oznacza, że można uzyskać do nich dostęp z dowolnego miejsca w programie. Ale możesz tworzyćprivate zmienne o nazwie lexical variables w dowolnym momencie z my operator.
Plik myoperator ogranicza zmienną do określonego regionu kodu, w którym może być używana i dostępna. Poza tym regionem nie można użyć tej zmiennej ani uzyskać do niej dostępu. Ten region nazywa się jego zasięgiem. Zakres leksykalny to zwykle blok kodu z zestawem nawiasów wokół niego, na przykład definiujących treść podprogramu lub oznaczających bloki kodu instrukcji if, while, for, foreach i eval .
Poniżej znajduje się przykład pokazujący, jak zdefiniować jedną lub wiele zmiennych prywatnych za pomocą my operator -
sub somefunc {
my $variable; # $variable is invisible outside somefunc()
my ($another, @an_array, %a_hash); # declaring many variables at once
}
Sprawdźmy następujący przykład, aby rozróżnić zmienne globalne i prywatne -
#!/usr/bin/perl
# Global variable
$string = "Hello, World!";
# Function definition
sub PrintHello {
# Private variable for PrintHello function
my $string; $string = "Hello, Perl!";
print "Inside the function $string\n"; } # Function call PrintHello(); print "Outside the function $string\n";
Kiedy powyższy program jest wykonywany, daje następujący wynik -
Inside the function Hello, Perl!
Outside the function Hello, World!
Wartości tymczasowe przez local ()
Plik localjest najczęściej używany, gdy bieżąca wartość zmiennej musi być widoczna dla wywoływanych podprogramów. Lokalny po prostu podaje tymczasowe wartości zmiennym globalnym (czyli pakietowym). Nazywa się to dynamicznym określaniem zakresu . Zakres leksykalny jest wykonywany za pomocą my, co działa bardziej jak automatyczne deklaracje języka C.
Jeśli parametr local zawiera więcej niż jedną zmienną lub wyrażenie, należy je umieścić w nawiasach. Ten operator działa poprzez zapisywanie bieżących wartości tych zmiennych na liście argumentów na ukrytym stosie i przywracanie ich po wyjściu z bloku, podprogramu lub eval.
Sprawdźmy następujący przykład, aby rozróżnić zmienne globalne i lokalne -
#!/usr/bin/perl
# Global variable
$string = "Hello, World!"; sub PrintHello { # Private variable for PrintHello function local $string;
$string = "Hello, Perl!"; PrintMe(); print "Inside the function PrintHello $string\n";
}
sub PrintMe {
print "Inside the function PrintMe $string\n"; } # Function call PrintHello(); print "Outside the function $string\n";
Kiedy powyższy program jest wykonywany, daje następujący wynik -
Inside the function PrintMe Hello, Perl!
Inside the function PrintHello Hello, Perl!
Outside the function Hello, World!
Zmienne stanu za pośrednictwem state ()
Istnieje inny typ zmiennych leksykalnych, które są podobne do zmiennych prywatnych, ale zachowują swój stan i nie są ponownie inicjowane po wielokrotnym wywołaniu podprogramów. Te zmienne są definiowane za pomocąstate operator i dostępne począwszy od Perla 5.9.4.
Sprawdźmy następujący przykład, aby zademonstrować użycie state zmienne -
#!/usr/bin/perl
use feature 'state';
sub PrintCount {
state $count = 0; # initial value print "Value of counter is $count\n";
$count++;
}
for (1..5) {
PrintCount();
}
Kiedy powyższy program jest wykonywany, daje następujący wynik -
Value of counter is 0
Value of counter is 1
Value of counter is 2
Value of counter is 3
Value of counter is 4
Przed Perl 5.10 musiałbyś napisać to w ten sposób -
#!/usr/bin/perl
{
my $count = 0; # initial value
sub PrintCount {
print "Value of counter is $count\n"; $count++;
}
}
for (1..5) {
PrintCount();
}
Kontekst wywołania podprogramu
Kontekst podprogramu lub instrukcji jest definiowany jako typ oczekiwanej wartości zwracanej. Pozwala to na użycie jednej funkcji, która zwraca różne wartości w zależności od tego, czego oczekuje użytkownik. Na przykład następująca metoda localtime () zwraca ciąg, gdy jest wywoływana w kontekście skalarnym, ale zwraca listę, gdy jest wywoływana w kontekście listowym.
my $datestring = localtime( time );
W tym przykładzie wartość $ timestr jest teraz ciągiem znaków składającym się z bieżącej daty i godziny, na przykład Thu 30 Nov 15:21:33 2000. I odwrotnie -
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
Teraz poszczególne zmienne zawierają odpowiednie wartości zwrócone przez podprogram localtime ().