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



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

CONDITION-PART ? TRUE-PART : FALSE-PART

Это, в свою очередь, является сокращением от вот такого кода:

if (CONDITION-PART) {
TRUE-PART
} else {
FALSE-PART
}

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

Работает все это следующим образом: проверяется условие "CONDITION-PART", если оно истинно, то выполняется часть "TRUE-PART", если же оно ложно, то выполняется часть "FALSE-PART".

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

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

$secondVar = ($firstVar == 0) ? 0 : $array[0];

здесь переменной $secondVar будет присвоено значение: 0 - если переменная $firstVar равна 0, и $array[0] (первый элемент массива $array) - если переменная не равна нулю.

Вы можете использовать вложенную форму данного оператора:

$firstVar = $temp == 0 ?
$numFiles++ :
($temp == 1 ?
$numRecords++ :
($temp == 3 ? $numBytes++ : $numErrors++));

А вот еще более странное (на первый взгляд) использование этого оператора:

$firstVar = 1;
$secondVar = 1;
$thirdVar = 1;
($thirdVar == 0 ? $firstVar : $secondVar) = 10;
print "$firstVar\n";
print "$secondVar\n";
print "$thirdVar\n";

в зависимости от значения переменной $thirdVar значение 10 может присваиваться одной из двух переменных - $firstVar и $secondVar.

Результатом работы программы будет: 1, 10, 1

Оператор интервала ".."

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

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

При использовании этого оператора в массивах, его результатом является просто создание последовательности символов. Рассмотрим пример с заданием массива чисел от 1 до 10:

@array(1..10);

Или, например, букв алфавита:

@array('a'..'z');

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

@array('a'..'z', 1..10, 'abc');
@array('01'..'10'); - 01, 02, 03, .., 10

Вы также можете использовать переменные в качестве операндов этого оператора:

$var=10;
@array(1..$var);

А что произойдет, если задать в качестве операнда не одну букву, а две? Например:

@array('aa'..'ba');

В данном случае Perl будет производить инкремент правой крайней буквы первого операнда ('aa') до тех пор, пока этой буквой не станет 'z'. Затем Perl произведет инкремент левой буквы первого операнда (буква 'a' превратится в 'b'), а потом снова примется за инкремент правой, получив в итоге 'ba'.

Строковые операторы "." и "x"

В Perl имеется два оператора для манипуляций со строками - операция конкатенации (объединения) - "." и операция репликации (повторения) - "x". Как вы уже поняли, первый оператор предназначен для объединения нескольких строк в одну, а второй оператор - для получения нескольких копий одной строки.

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

Оператор предназначен для объединения двух строк в одну. Если в качестве одного из операндов выступает числовое значение, то оно тут же будет преобразовано в строковое.

$firstVar = "This box can hold " . 55 . " items.";
print("$firstVar\n");

Результатом работы будет: This box can hold 55 items.

В качестве операндов вы также можете использовать переменные.

Использование оператора репликации (повтора)

Этот оператор призван обеспечивать возможность повтора строки некоторое количество раз. Как и в предыдущем случае, любое числовое значение, выступающее в качестве операнда, будет немедленно преобразовано в строковое.

$firstVar = "1";
$secondVar = $firstVar x 7;
print("$secondVar\n");
Результатом работы будет: 1111111

Если в качестве операнда выступает массив, то он рассматривается как скаляр, то есть на его место подставляется количество элементов массива.

Операторы присваивания

Последний тип операторов, который мы сегодня рассмотрим, это операторы присваивания. Один из них, оператор "=", вы уже использовали раньше, чтобы присваивать значения переменным. Помимо этого, Perl также имеет несколько операторов, которые являются сокращенными вариантами использования основного оператора присваивания "=" и какого-либо другого оператора. Например, вместо употребления $var1=$var1+$var2 вы можете запросто написать $var1 += $var2. И это будет работать. Преимущество использования сокращенной формы состоит в том, что вам придется меньше набирать текста.

Вот операторы, которые вы можете использовать в паре с основным оператором присваивания "=":
"+","-","*","/","%",".","**","x","<<",">>","&","|',"||","^"

Приоритет выполнения операторов
Уровень Оператор Обработка 22 (), [], {} Слева направо
21 -> Слева направо
20 ++, -- Нет
19 ** Справа налево
18 !, ~, +,+, -,\ Справа налево
17 =~, !~ Слева направо
16 *, /, % x Слева направо
15 +, -,. Слева направо
14 <<,>> Слева направо
13 Нет
12 Нет
11 Нет
10 & Слева направо
9 |, ^ Слева направо
8 && Слева направо
7 || Слева направо
6 .. Нет
5 ?: Справа налево
4 Справа налево
3 , Слева направо
2 not Слева направо
1 and Слева направо
0 or, xor Слева направо

Здесь описано, какой оператор какой имеет приоритет - чем выше уровень, тем выше приоритет. В выражении с несколькими операторами в первую очередь обрабатываются те, у которых выше приоритет.

В таблице есть некоторые операторы, с которыми вы еще не знакомы, - о них вы узнаете позднее.

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

…ух, еще одна глава позади… :)))

Глава 4

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

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

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

$areaOfFirstCircle = areaOfCircle($firstRadius);

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

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

Давайте присмотримся к вызову функции - сначала мы видим скалярную переменную, затем - оператор присвоения. Вы уже знаете, что это означает - Perl присвоит переменной $areaOfFirstCircle значение, стоящее справа от знака присваивания. Но что в действительности стоит справа?

Первое, что вы видите - это имя функции areaOfCircle(). Круглые скобки справа и отсутствие перед именем символов $, @ и % говорит о том, что это - вызов функции. Внутри круглых скобок содержится список параметров или значений, передающихся функции.

Вычисление площади круга:

$areaOfFirstCircle = areaOfCircle(5);
print("$areaOfFirstCircle\n");
sub areaOfCircle {
$radius = $_[0];
return(3.1415 * ($radius ** 2));
}

Программа напечатает:

78.7375

Объявление функции:

sub имяФункции {
тело функции
}

И все. Ваша функция готова.

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

Внутри функции массив параметров имеет имя @_. Все параметры, передаваемые функции, содержатся в массиве @_, откуда их можно извлечь при необходимости.

Наша маленькая функция из примера выше могла бы сделать это следующей строкой:

$radius = $_[0];

Эта строка присваивает первый элемент массива @_ скалярной переменной $radius.

Если вы хотите, вы можете не использовать в функции оператор return для возврата значения, - Perl автоматически возвратит значение последнего вычисленного выражения. Но будет лучше, если вы все же будете использовать оператор return - так вы избежите многих случайных ошибок.

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

Использование массива параметров (@_)

Как уже говорилось ранее - все параметры функция может найти в массиве параметров @_. Это очень удобно - чтобы узнать, сколько параметров было передано функции, нужно всего лишь обратиться к массиву параметров @_ в скалярном контексте.

firstSub(1, 2, 3, 4, 5, 6);
firstSub(1..3);
firstSub("A".."Z");
sub firstSub {
$numParameters = @_ ;
print("The number of parameters is $numParameters\n");
}

Программа напечатает:

The number of parameters is 6

The number of parameters is 3

The number of parameters is 26

Perl позволяет вам передавать в функцию любое число параметров. Функция сама может определить, какие параметры ей использовать, и в какой последовательности. Массив параметров @_ может использоваться так же, как и любой другой массив.

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

areaOfRectangle(2, 3);
areaOfRectangle(5, 6);
sub areaOfRectangle {
($height, $width) = @_ ;
$area = $height * $width;
print("The height is $height. The width is $width. The area is $area.\n\n");
}

Программа напечатает:

The height is 2. The width is 3. The area is 6.

The height is 5. The width is 6. The area is 30.

Передача параметров функции по ссылке.

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

@array = (0..5);
print("Before fuNCtion call, array = @array\n");
firstSub(@array);
print("After fuNCtion call, array = @array\n");
sub firstSub{
$_[0] = "A";
$_[1] = "B";
}

Программа напечатает:

Before fuNCtion call, array = 0 1 2 3 4 5

After fuNCtion call, array = A B 2 3 4 5

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

Вот пример той же программы, но написанной более правильно:

@array = (0..5);
print("Before fuNCtion call, array = @array\n");
firstSub(@array);
print("After fuNCtion call, array = @array\n");
sub firstSub{
($firstVar, $secondVar) = @_ ;
$firstVar = "A";
$secondVar = "B";
}

Программа напечатает:

Before fuNCtion call, array = 0 1 2 3 4 5

After fuNCtion call, array = 0 1 2 3 4 5

Как вы видите - функция присваивает значения переданных ей параметров новым переменным, и оперирует в дальнейшем только ими - не изменяя непосредственно массив параметров.

Но тогда вы можете столкнуться с другой проблемой:

$firstVar = 10;
@array = (0..5);
print("Before fuNCtion call\n");
print("\tfirstVar = $firstVar\n");
print("\tarray = @array\n");
firstSub(@array);
print("After fuNCtion call\n");
print("\tfirstVar = $firstVar\n");
print("\tarray = @array\n");
sub firstSub{
($firstVar, $secondVar) = @_ ;
$firstVar = "A";
$secondVar = "B";
}

Программа напечатает:

Before fuNCtion call
firstVar = 10
array = 0 1 2 3 4 5

After fuNCtion call
firstVar = A
array = 0 1 2 3 4 5

То есть, по умолчанию все переменные в Perl-программе доступны из любого фрагмента кода. Это очень удобно во многих случаях, но нередко доставляет неудобства и приводит к неприятным ошибкам. Далее вы узнаете, как создавать переменные, видимые только внутри соответствующих функций.

Области действия переменных.

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

Иногда бывает очень полезным ограничить область действия той или иной переменной внутри какой-либо функции. В этом случае изменение значения переменной внутри функции никак не отразится на остальных частях программы. В Perl имеются две функции - my() и local(). Первая создает переменную, которая видна только внутри данной функции. Вторая создает переменную, которую также могут "видеть" функции, вызванные из данной функции.

firstSub("AAAAA", "BBBBB");
sub firstSub{
local ($firstVar) = $_[0];
my($secondVar) = $_[1];
print("firstSub: firstVar = $firstVar\n");
print("firstSub: secondVar = $secondVar\n\n");
secondSub();
print("firstSub: firstVar = $firstVar\n");
print("firstSub: secondVar = $secondVar\n\n");
}

sub secondSub{
print("secondSub: firstVar = $firstVar\n");
print("secondSub: secondVar = $secondVar\n\n");
$firstVar = "ccccC";
$secondVar = "DDDDD";
print("secondSub: firstVar = $firstVar\n");
print("secondSub: secondVar = $secondVar\n\n");
}

Программа напечатает:

firstSub: firstVar = AAAAA
firstSub: secondVar = BBBBB
secondSub: firstVar = AAAAA
Use of uninitialized value at test.pl line 19.
secondSub: secondVar =
secondSub: firstVar = ccccC
secondSub: secondVar = DDDDD
firstSub: firstVar = ccccC
firstSub: secondVar = BBBBB

Как вы видите, функция secondSub() не имеет доступа к переменной $secondVar, которая была создана функцией my() внутри функции firstSub(). Perl даже вывел сообщение, предупреждая вас об этом. В то же время, переменная $firstVar доступна и может быть изменена функцией secondSub().

По возможности старайтесь обходиться только функцией my() и не использовать функцию local() - так вы обеспечите себе более строгий контроль над областью действия переменных.

На самом деле, функция my() гораздо более сложна и функциональна. Но об этом пойдет речь в главе 15 - "Модули Perl".

Вы помните, в чем разница между передачей параметров функции по ссылке и по значению? Если вы передаете параметры по значению, то функция не может изменять значения переданных ей параметров (переменных), а значит это никак не отразится на всей программе. Если же вы передаете параметры по ссылке, то функция может изменять значения параметров (переменных), и это отразится на основной программе. Так вот, при использовании функции local() метод передачи параметров по ссылке работает немного по-другому - функции могут менять значения переданных им параметров (переменных), но это отразится только на самой "верхней" функции - той, где была использована функция local(), - на основную же программу это никак не повлияет.

Использование списка в качестве параметра функции.

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

firstSub((0..10), "AAAA");
sub firstSub{
local(@array, $firstVar) = @_ ;
print("firstSub: array = @array\n");
print("firstSub: firstVar = $firstVar\n");
}

Программа напечатает:

firstSub: array = 0 1 2 3 4 5 6 7 8 9 10 AAAA
Use of uninitialized value at test.pl line 8.
firstSub: firstVar =

Вы видите, что при инициализации переменных массив @array поглощает все элементы массива параметров @_, ничего не оставляя скаларной переменной $firstVar. Это подтверждает и предупреждающее сообщение интерпретатора Perl. Вы можете решить данную проблему путем перестановки местами параметров - если вы поставите сначала скалярную переменную, а потом массив, то все будет так как надо:

firstSub("AAAA", (0..10));
sub firstSub{
local($firstVar, @array) = @_ ;
print("firstSub: array = @array\n");
print("firstSub: firstVar = $firstVar\n");
}

Программа напечатает:

firstSub: array = 0 1 2 3 4 5 6 7 8 9 10
firstSub: firstVar = AAAA

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


Дата добавления: 2018-04-04; просмотров: 383; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!