Анимация
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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

При передаче подпрограмме массива или хэша вы рискуете здорово ошибиться,

если таких массивов несколько. Посмотрите на данный фрагмент кода:

sub display arrays { (da, §b)=e ;

print "Первый Ш-Ссив: ва\п"; print "Второй 1уассив: §b\n";

dispay arrays(gfirst, isecond) ;

Массив irst cond передаются при вызове подпрограммы в одном списке ? . Внутри этого большого плоского списка невозможно определить конец первого массива и начало второго. В подпрограмме оператор присваивания (§а, @Ь)=? приводит к тому, что все элементы массива в становятся элементами массива Sa, а массив 8Ь так и останется пустым списком. Чтобы вспомнить, почему это происходит, обратитесь к материалу 4-го занятия, "Укладка строительных блоков: списки и массивы".

Можно довольно просто передать в подпрограмму группу скалярных переменных и один массив или хэш. Для этого достаточно знать количество передаваемых скаляров и поместить массив или хэш последним в списке аргументов. В этом случае понятно, что после скаляров все оставшиеся аргументы принадлежат массиву или хэшу:

sub lots of args {

($first, $second, $tMrd, iarray)=e ; t Ссталывя часть грппрохрамуы...

lots of args{Sfoo, $fcar, $fcaz, gmyarray);

Если нужно передать в подпрограмму несколько массивов или хэшей, а затем отделить их друг от друга, используйте указатели. О том, как передавать в подпрограммы указатели, речь пойдет на 13-м занятии, "Структуры и ссылки".

Область видимости

Из введения к этому занятию вы узнали, что подпрограммы позволяют сгруппировать фрагменты кода и дать им имена, которые затем можно использовать для вызова этих фрагментов кода из любого нужного места программы. Подпрограммы позволяют создать функционально законченные модули, решающие универсальные задачи. На основе переданных аргументов, встроенных функций и выражений подпрограмма возвращает определенное значение. Вы можете использовать эту подпрограмму в других программах, так как ее выполнение не зависит от окружающего контекста, - она просто берет аргументы, внутренние данные и на их основании вычисляет возвращаемое значение. Функция становится как бы "черным ящиком", который связывают с внешним миром только входные и выходные значения. Такие функции называются строгими.

А теперь давайте проанализируем два следующих фрагмента кода.

t Один из хороших стилей написания функици sub moonweight {

{$weight)=g ;

return {?weight/6);

print moonweight (150);

♦ ПЛсхсй ст1ь написания подобней функции.

1 Чть I. ;Ei Perl



aibmoonveight {

return(Sweight/6);

$weight=150; pcdntmoonweigbt;

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

Итак, первый вариант реализации лучше, но в нем по-прежнему чего-то не хватает. Переменная $weight может конфликтовать с другой переменной с подобным именем, если та встречается в программе.

позволяет использовать одни и те же имена для обозначения различных переменных в большой программе. По умолчанию переменные Perl видимы в основной программе и в подпрограммах. Это так называемые глобальные переменные.

Допустим, вам нужно создать переменную, относящуюся только к данной функции. Для этого следует воспользоваться оператором ту:

sub moonweight { шу $weight; (Sweight)=ej

return($4eight/l.66667);

Внутри функции moonweight () переменная $weight является приватной переменной. Другие функции программы не имеют доступа к этой переменной. Таким образом, все другие переменные с именем Sweight не пересекаются с переменной Sweight функции Теперь подпрограмма совершенно изолирована от остальной части программы.

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

Оператор ту можно использовать для объявления скаляров, массивов и хэшей, как приватных переменных подпрограммы. Дескрипторы файлов, подпрограммы и специальные переменные Perl и др.) нельзя объявить приватными переменными. Можно объявлять сразу несколько переменных, поместив их имена в скобки:

пу ($1аггу, Bcurly, tmoe);

Приватные переменные хранятся совсем не так, как глобальные. Глобальные и приватные переменные могут иметь одинаковые имена, но при этом не конфликтовать, как показано ниже:

suunc {

ny $x;

print

$х=10; i гбсная пЕрхнЕзая $х pdnt "$х\п"; myfuncO; print "Sx\n";



В результате выполнения этого примера будут выведены числа 10, 20, а затем снова 10. Переменные $х в функции myfunc() и $х в основной части программы - совершенно разные. У вас может возникнуть один резонный вопрос: "Возможно ли в подпрограмме использовать как приватную, так и глобальную переменную с одним и тем же именем?" Да, но это достаточно сложный вопрос, обычно не рассматриваемый начальными учебными пособиями по Perl.

Как правило, любая подпрограмма на Perl начинается с объявления приватных неременных и присваивания массива списку этих неременных:

sub playerstats {

my ($at bats, $hits, Swalks) =в ;

t Ссталывя часть фджцда...

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

Использование оператора ту

Можно объявить переменные даже с меньшей областью видимости, чем целая подпрограмма. Для этого следует поместить оператор ту в блок. Это может быть как

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

$У=20;

ту $у=500;

print • Значение пераувэнной \$у равно $у\п"; * Напечатает 500

print " $у \ п "; # Напечатает 2 О

Объявлять переменные можно даже внутри управляющей структуры, такой как for,

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

while($testval) {

т/ $stuff; ♦ Переменная ввдима только вьчри пжла

foreach(et) {

f видим только внутри цикла foreach

Здесь переменные, объявленные в операторе заново создаются во время каждой итерации цикла.

В Perl версии 5.004 и выше можно переменную (итератор) цикла for или foreach, a

также условное выражение структур while или if объявить приватными для блока: foreach t {iarray) {

t ПёрЕМЕнная $elarent ввдфн только m/ipi цжпа foreach () }

130 Часть I. Ос1 Perl



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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122