Учебники

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 компилирует вашу программу перед ее выполнением, не имеет значения, где вы объявляете свою подпрограмму.

Live Demo

#!/usr/bin/perl

# Function definition
sub Hello {
   print "Hello, World!\n";
}

# Function call
Hello();

Когда вышеуказанная программа выполняется, она дает следующий результат —

Hello, World!

Передача аргументов в подпрограмму

Вы можете передавать различные аргументы подпрограмме, как это делается на любом другом языке программирования, и они могут быть доступны внутри функции с помощью специального массива @_. Таким образом, первый аргумент функции находится в $ _ [0], второй — в $ _ [1] и так далее.

Вы можете передавать массивы и хэши в качестве аргументов, как и любой скаляр, но передача более одного массива или хэша обычно приводит к потере их отдельных идентификаторов. Поэтому мы будем использовать ссылки (объясненные в следующей главе) для передачи любого массива или хэша.

Давайте попробуем следующий пример, который берет список чисел и затем печатает их среднее значение —

Live Demo

#!/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 принимает и анализирует списки и массивы, может быть трудно извлечь отдельные элементы из @_. Если вам нужно передать список вместе с другими скалярными аргументами, то сделайте список последним аргументом, как показано ниже —

Live Demo

#!/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

Передача хешей в подпрограммы

Когда вы предоставляете хеш для подпрограммы или оператора, который принимает список, тогда хеш автоматически переводится в список пар ключ / значение. Например —

Live Demo

#!/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

Возвращаемое значение из подпрограммы

Вы можете вернуть значение из подпрограммы, как и на любом другом языке программирования. Если вы не возвращаете значение из подпрограммы, то любое вычисление, которое в последний раз выполнялось в подпрограмме, автоматически также будет возвращаемым значением.

Вы можете возвращать массивы и хэши из подпрограммы, как и любой скаляр, но возвращая более одного массива или хеша, обычно они теряют свои отдельные идентификаторы. Поэтому мы будем использовать ссылки (объясненные в следующей главе), чтобы вернуть любой массив или хеш из функции.

Давайте попробуем следующий пример, который берет список чисел, а затем возвращает их среднее значение —

Live Demo

#!/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 являются глобальными переменными, что означает, что к ним можно получить доступ из любой точки программы. Но вы можете в любое время создавать частные переменные, называемые лексическими переменными, с помощью оператора 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
}

Давайте проверим следующий пример, чтобы различить глобальные и частные переменные:

Live Demo

#!/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 ()

Локальное в основном используется, когда текущее значение переменной должно быть видимым для вызываемых подпрограмм. Локальный просто дает временные значения глобальным (то есть пакет) переменным. Это известно как динамическое определение объема . С помощью my выполняется лексическая область видимости, которая больше похожа на автоматические объявления Си.

Если для локальной переменной задано более одной переменной или выражения, они должны быть заключены в скобки. Этот оператор работает, сохраняя текущие значения этих переменных в своем списке аргументов в скрытом стеке и восстанавливая их при выходе из блока, подпрограммы или eval.

Давайте проверим следующий пример, чтобы различать глобальные и локальные переменные —

Live Demo

#!/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 ()

Есть еще один тип лексических переменных, которые похожи на частные переменные, но они поддерживают свое состояние и не инициализируются повторно при множественных вызовах подпрограмм. Эти переменные определяются с помощью оператора состояния и доступны начиная с Perl 5.9.4.

Давайте проверим следующий пример, чтобы продемонстрировать использование переменных состояния

Live Demo

#!/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 вы должны были бы написать это так:

Live Demo

#!/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 теперь является строкой, состоящей из текущей даты и времени, например, чт 30 ноября 15:21:33 2000. И наоборот —

($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);

Теперь отдельные переменные содержат соответствующие значения, возвращаемые функцией localtime ().