Perl - подпрограммы
Подпрограмма или функция Perl - это группа операторов, которые вместе выполняют задачу. Вы можете разделить свой код на отдельные подпрограммы. Как разделить код между различными подпрограммами - решать вам, но логически разделение обычно таково, что каждая функция выполняет определенную задачу.
В Perl термины «подпрограмма», «метод» и «функция» взаимозаменяемы.
Определить и вызвать подпрограмму
Общая форма определения подпрограммы на языке программирования Perl выглядит следующим образом:
sub subroutine_name {
body of the subroutine
}
Типичный способ вызова этой подпрограммы Perl следующий:
subroutine_name( list of arguments );
В версиях Perl до 5.0 синтаксис вызова подпрограмм немного отличался, как показано ниже. Это по-прежнему работает в новейших версиях Perl, но не рекомендуется, так как он обходит прототипы подпрограмм.
&subroutine_name( list of arguments );
Давайте посмотрим на следующий пример, в котором определяется простая функция, а затем вызывается ее. Поскольку Perl компилирует вашу программу перед ее выполнением, не имеет значения, где вы объявляете свою подпрограмму.
#!/usr/bin/perl
# Function definition
sub Hello {
print "Hello, World!\n";
}
# Function call
Hello();
Когда вышеуказанная программа выполняется, она дает следующий результат -
Hello, World!
Передача аргументов подпрограмме
Вы можете передавать подпрограмме различные аргументы, как и в любом другом языке программирования, и к ним можно получить доступ внутри функции с помощью специального массива @_. Таким образом, первый аргумент функции находится в $ _ [0], второй - в $ _ [1] и так далее.
Вы можете передавать массивы и хэши в качестве аргументов, как любой скаляр, но передача более одного массива или хэша обычно приводит к потере их отдельных идентификаторов. Поэтому мы будем использовать ссылки (объясненные в следующей главе) для передачи любого массива или хэша.
Давайте попробуем следующий пример, который берет список чисел и затем выводит их среднее значение -
#!/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);
Когда вышеуказанная программа выполняется, она дает следующий результат -
Average for the given numbers : 20
Передача списков в подпрограммы
Поскольку переменная @_ является массивом, ее можно использовать для предоставления списков подпрограмме. Однако из-за способа, которым Perl принимает и анализирует списки и массивы, может быть трудно извлечь отдельные элементы из @_. Если вам нужно передать список вместе с другими скалярными аргументами, сделайте список последним аргументом, как показано ниже -
#!/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);
Когда вышеуказанная программа выполняется, она дает следующий результат -
Given list is 10 1 2 3 4
Передача хэшей подпрограммам
Когда вы предоставляете хеш подпрограмме или оператору, который принимает список, он автоматически преобразуется в список пар ключ / значение. Например -
#!/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);
Когда вышеуказанная программа выполняется, она дает следующий результат -
name : Tom
age : 19
Возврат значения из подпрограммы
Вы можете вернуть значение из подпрограммы, как и в любом другом языке программирования. Если вы не возвращаете значение из подпрограммы, то любое вычисление, выполненное последним в подпрограмме, автоматически также является возвращаемым значением.
Вы можете возвращать массивы и хэши из подпрограммы, как любой скаляр, но возвращение более одного массива или хэша обычно приводит к потере их отдельных идентификаторов. Поэтому мы будем использовать ссылки (объясненные в следующей главе) для возврата любого массива или хэша из функции.
Давайте попробуем следующий пример, который берет список чисел, а затем возвращает их среднее значение:
#!/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";
Когда вышеуказанная программа выполняется, она дает следующий результат -
Average for the given numbers : 20
Частные переменные в подпрограмме
По умолчанию все переменные в Perl являются глобальными переменными, что означает, что к ним можно получить доступ из любого места в программе. Но вы можете создатьprivate переменные, называемые lexical variables в любое время с my оператор.
В myОператор ограничивает переменную определенной областью кода, в которой она может быть использована и доступна. За пределами этого региона эту переменную нельзя использовать или получить к ней доступ. Этот регион называется его размахом. Лексическая область видимости обычно представляет собой блок кода с набором фигурных скобок вокруг него, например, те, которые определяют тело подпрограммы или обозначают блоки кода операторов if, while, for, foreach и eval .
Ниже приведен пример, показывающий, как определить одну или несколько частных переменных с помощью my оператор -
sub somefunc {
my $variable; # $variable is invisible outside somefunc()
my ($another, @an_array, %a_hash); # declaring many variables at once
}
Давайте проверим следующий пример, чтобы различать глобальные и частные переменные -
#!/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";
Когда вышеуказанная программа выполняется, она дает следующий результат -
Inside the function Hello, Perl!
Outside the function Hello, World!
Временные значения через local ()
В localчаще всего используется, когда текущее значение переменной должно быть видно вызываемым подпрограммам. Локальный просто дает временные значения глобальным (то есть пакетным) переменным. Это известно как динамическая область видимости . Лексическая область видимости выполняется с помощью my, который больше похож на автоматические объявления C.
Если в local дано более одной переменной или выражения, они должны быть заключены в круглые скобки. Этот оператор работает, сохраняя текущие значения этих переменных в своем списке аргументов в скрытом стеке и восстанавливая их при выходе из блока, подпрограммы или eval.
Давайте проверим следующий пример, чтобы различать глобальные и локальные переменные -
#!/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";
Когда вышеуказанная программа выполняется, она дает следующий результат -
Inside the function PrintMe Hello, Perl!
Inside the function PrintHello Hello, Perl!
Outside the function Hello, World!
Переменные состояния через state ()
Есть еще один тип лексических переменных, которые похожи на частные переменные, но сохраняют свое состояние и не инициализируются повторно при многократных вызовах подпрограмм. Эти переменные определяются с помощьюstate оператор и доступен начиная с Perl 5.9.4.
Давайте проверим следующий пример, чтобы продемонстрировать использование state переменные -
#!/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();
}
Когда вышеуказанная программа выполняется, она дает следующий результат -
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
До Perl 5.10 вам приходилось писать так:
#!/usr/bin/perl
{
my $count = 0; # initial value
sub PrintCount {
print "Value of counter is $count\n";
$count++;
}
}
for (1..5) {
PrintCount();
}
Контекст вызова подпрограммы
Контекст подпрограммы или оператора определяется как тип ожидаемого возвращаемого значения. Это позволяет вам использовать одну функцию, которая возвращает разные значения в зависимости от того, что пользователь ожидает получить. Например, следующая функция localtime () возвращает строку, когда она вызывается в скалярном контексте, но возвращает список, когда она вызывается в контексте списка.
my $datestring = localtime( time );
В этом примере значение $ timestr теперь представляет собой строку, состоящую из текущей даты и времени, например, Thu Nov 30 15:21:33 2000. И наоборот -
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
Теперь отдельные переменные содержат соответствующие значения, возвращаемые подпрограммой localtime ().