Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [ 40 ] 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

Одна подпрограмма может вызывать другую подпрограмму, которая, в свою очередь, может вызывать третью подпрограмму и т.д., пока вся наличная память не будет заполнена адресами возврата и не полностью вычисленными выражениями. (Ведь настоящего программиста вряд ли удовлетворят какие-то 8 или 32 уровня вложенности подпрограмм.)

Возвращаемые значения

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

Давайте, например, определим такую подпрограмму:

sub sum of a and b { return $а + $b;

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

$а = 3; $Ь = 4;

$с = sum of a and b(); # $с присваивается значение 7

Sd = 3 * sum of a and b(); # Sd содержит значение 21

При вычислении в списочном контексте подпрограмма может возвращать список значений. Рассмотрим такую подпрограмму и ее вызов:

sub list of a and b (

return(Sa,Sb);

Sa =5; Sb = 6;

@c = list of a and b(); # @c присваивается значение (5,6)

Последнее вычисленное выражение действительно означает последнее вычисленное выражение, а не последнее выражение, определенное в теле подпрограммы. Например, следующая подпрограмма возвращает $а, если $а > 0; в противном случае она возвращает $Ь:

sub gimme a or b ( if (Sa > 0) (

print "choosing a (Sa)\n"; returns Sa; } else {

print "choosing b (Sb)\n"; returns Sb;



Все это довольно тривиальные примеры. Однако будет гораздо лучше, если вместо того, чтобы полагаться на глобальные переменные, мы сможем передавать в подпрограмму значения, разные для каждого вызова. Именно к этому мы сейчас и перейдем.

Аргументы

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

В Perl после вызова подпрограммы следует список, заключенный в круглые скобки, которые обеспечивают автоматическое присваивание элементов данного списка на период выполнения этой подпрограммы специальной переменной с именем @ . Подпрограмма может обратиться к этой переменной и получить число аргументов и их значения. Например:

sub say hello to {

print "hello, S [0]!\n" # первый параметр

Здесь мы видим ссылку на $ [0] - первый элемент массива Обратите внимание: несмотря на внешнее сходство, значение $ [0] (первый элемент массива @ ) не имеет ничего общего с переменной $ (самостоятельной скалярной переменной). Не путайте их! Из этого кода видно, что подпрограмма приветствует того, чье имя мы указываем в качестве первого параметра. Это значит, что ее можно вызвать так:

say hello to ( "world") ,- # выдает hello, world $.4 = "somebody";

say hello to($x); # выдает hello, somebody

say hello to("me")+say hello to("you") ; # a теперь приветствует себя и вас

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

Вот пример с использованием более одного параметра:

sub say (

print "S [0], $ [1]!\n";

say("hello", "world"); # опять hello world

say ("goodbye", "cruel world"); # goodbye cruel world - популярная фраза из фильмов

Избыточные параметры игнорируются, т.е. если вы никогда не загл5щы-ваете в $ [3], языку Perl это абсолютно все равно. Недостающие пара\:етры также игнорируются, и если вы попытаетесь обратиться за пределы цасспш @ , как и любого другого массива, то просто получите в ответ undef.

128 llaijHfiCM Perl



Переменная @ является локальной для подпрограммы. Если для @ установлено глобальное значение, то оно перед вызовом подпрограммы сохраняется, а после возврата из подпрограммы восстанавливается. Это также означает, что подпрограмма может передавать аргументы в другую подпрограмму, не боясь "потерять" собственную переменную @ ; вложенный вызов подпрофам-мы точно так же получает собственную переменную @ .

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

sub add two (

return $ [0] + 5 tl];

print add two(3,4); # выводит значение 7

$c = add two(5,6); # $c получает значение 11

Давайте обобщим эту подпрограмму. Что, если нам нужно сложить 3, 4 или 100 значений? Это можно было бы сделать с помощью цикла, например:

sub add (

Ssum =0; # инициализировать сумму

foreach ((? ) (

$sum += $ ; # прибавить все элементы

leturn Ssum # последнее вычисленное выражение: сумма веек элементов

Sa = add(4,5,6); # складывает 4+5+6=15 и присваивает переменной Sa

print add(1,2,3,4,5); # выводит 15

print add (1..5); # тоже выводит 15, потому что список 1..5 раскрывается

Что, если бы переменная с именем $sum использовалась у нас раньше? При вызове подпрограммы add мы просто потеряли бы ее значение. В следу10щем разделе мы увидим, как избежать этого.

Локальные переменные в функциях

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

sub add {

my (Ssum); # сделать Ssum локальной переменной

Ssum =0; # инициализировать сумму



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [ 40 ] 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103