Требуется закрепить за скалярной переменной значение по умолчанию, но лишь в том случае, если оно не было задано ранее. Довольно часто требуется, чтобы стандартное значение переменной жестко кодировалось в программе, но его можно было переопределить из ко
Решение
Воспользуйтесь оператором || или ||=, работающим как со строками, так и с числами:
# Использовать $Ь, если. Значение $B истинно, и $с в противном случае $а = $Ь || $с;
# Присвоить $х значение $у. носишь в том случае,
# если $х не является истинной $х ||= $у;
Если ваша переменная может принимать значения Одни "0", воспользуйтесь функцией defined
#использоватъ $b если значение $b определено , и $с в противном
случае $а =defined($b) ? $b : $c
Комментарий
Главное отличие между этими двумя приемами (defined и ||) состоит, прежде всего, в том, что именно проверяется - определенность или истинность, В мире Perl три определенных значения являются ложными: О, "О" и "". Если ваша переменная содержит одну из этих
В отличие от других языков, где возвращаемые значения ограничиваются 6 и 1, оператор 11 Perl обладает более интересным свойством: он возвращает первый (левый) операнд, если тот имеет истинное значение; в противном случае возвращается второй операнд. Опера
Это позволяет установить значение по умолчанию для переменной, функции или более длинного выражения в том случае, если первый операнд не подходит. Ниже приведен пример использования ||, в котором $foo присваивается либо $bar, либо, если значение $bаr ложн
$foo = $bar || "DEFAULT VALUE"
В другом примере переменной $dir присваивается либо первый аргумент командной строки программы, либо "/tmp", если аргумент не указан:
$dir = shift(@ARGV) || "/tmp" То же самое можно делать и без изменения @ARGV: $dir = $ARGV[0] || "/tmp"
Если 0 является допустимым значением $ARGV[0], использовать || нельзя, потому что вполне нормальное значение будет интерпретировано как ложное. Приходится обращаться к тернарному оператору выбора:
$dir = defined($ARGV[0]) ? shift(@"ARGV) : "/tmp";
To же можно записать и иначе, со слегка измененной семантикой: $dir = @ARGV ? $ARGV[0] : "/tmp"
Мы проверяем количество элементов в @ARGV. В условии оператора выбора (?:) @ARGV интерпретируется в скалярном контексте. Значение будет ложным лишь при нулевом количестве элементов, в этом случае будет использоваться "/tmp". Во всех остальных ситуациях пе
Следующая строка увеличивает значение %count, при этом в качестве ключа используется значение $shell, а если оно ложно - строка "/bin/sh".
$count{ $shell || "/bin/sh" }++,
В одном условии можно объединить несколько альтернативных вариантов, как показывает следующий пример. Результат совпадает с первым операндом, имеющим истинное значение.
# Определить имя пользователи всистеме UNIX $user = $ENV{USER} || $ENV{LOGNAME}
|| getlogin()
|| (getwuid($<))[0]
|| "Unknown uid number $<";
Оператор && работает аналогично; он возвращает первый операнд, если этот операнд ложен. В противном случае возвращается второй операнд. Поскольку ложные значения представляют интерес существенно реже, чем истинные, это свойство используется не так часто.
Оператор присваивания 11 = выглядит странно, но работает точно так же, как и остальные операторы присваивания. Практически для всех бинарных операторов Perl $VAR ОР= VALUE означает $VAR = $VAR OP VALUE; например, $а += $Ь-тоже, что и $а = $а + $Ь. Следова
В следующем примере 11= присваивает переменной $starting_point значение "Greenwich", если оно не было задано ранее. Предполагается, что $starting_point не принимает значений 0 или "0", а если принимает - то такие значения должны быть заменены:
$starting_point ||= "Greenwich"
В операторах присваивания 11 нельзя заменять оператором оr, поскольку or имеет слишком низкий приоритет. Выражение $а = $b or $с эквивалентно ($а = $b) or $c. В этом случае переменной $Ь всегда присваивается $а, а это совсем не то, чего вы добивались.
Не пытайтесь распространить это любопытное применение 11 и 11 = со скалярных величин на массивы и хэши. У вас ничего не выйдет, потому что левый операнд интерпретируется в скалярном контексте. Приходится делать что-нибудь подобное:
@а = @b unless @a; # Копировать, если массив пуст
@а = @>Ь ? @Ь : @с; # Присвоить @Ь, если он не пуст, иначе @с
> Смотри также
Описание оператора || в perlop(1); описание функций defined и exists в
perlfunc(1).
Требуется поменять значения двух скалярных переменных, но вы не хотите использовать временную переменную.
Решение
Воспользуйтесь присваиванием по списку: ($VAR1, $VAR2) = ($VAR2, $VAR1);
Комментарий
В большинстве языков программирования перестановка значений двух переменных требует промежуточного присваивания:
$temp = $a;
$а = $Ь;
$b = $temp;
В Perl дело обстоит иначе. Язык следит за обеими сторонами присваивания и за тем, чтобы ни одно значение не было случайно стерто. Это позволяет избавиться от временных переменных:
$а = "alpha";
$b = "omega";
($а, $b) = ($Ь, $а); # Первый становится последним - и наоборот
Подобным способом можно поменять местами сразу несколько переменных: ($alpha, $beta, $production) = qw(January March August);
# beta перемещается в alpha, # production - в beta,
# alpha - в production o
($alpha, $beta, $production) = ($beta, $production, $alpha);
После завершения этого фрагмента значения переменных
$alpha, $beta и $production будут равны соответственно "March", "August" и "January".
> Смотри также ---------------------------v
Раздел "List value constructors" perlop(1).
Требуется вывести код, соответствующий некоторому символу в кодировке ASCII, или наоборот - символ по ASCII-коду.
Решение
Воспользуйтесь функцией ord для преобразования символа в число или функцией сhr - для преобразования числа в символ:
$num = ord($char);
$char = chr($num);
Формат %с в функциях printf и sprintf также преобразует число в символ: $char = sprintf ("%с", $num); # Медленнее, чем chr($num) printf("Number %d is character %c\n", $num, $num);
Number 101 is character e
Шаблон С*, используемый в функциях pack и unpack, позволяет быстро преобразовать несколько символов: ,
@АSCII= unpack("C*". $string);
@STRING = pack("С*", $ascii);
Комментарий
В отличие от низкоуровневых, нетипизованных языков вроде ассемблера, Perl не считает эквивалентными символы и числа; эквивалентными считаются строки и числа. Это означает, что вы не можете произвольно присвоить вместо символа его числовое представление, и
$ascii_value = ord("e"); # Теперь 101
$character = chr(101); # Теперь "e"
Символ в действительности представляется строкой единичной длины, поэтому его можно просто вывести функцией print или с помощью формата %s функций printf и sprintf. Формат %с заставляет printf или sprintf преобразовать число в символ, однако он не позволя
printf("Number %d is character %c\n",101,101);
Функции pack" unpack, chr и ord работают быстрее, чем sprintf. Приведем, пример практического применения pack x unpack:
@ascii_character_numbers с unpack("C*", "sasample"); print "@ascii_character_ numbers \n";
115 97 109 112 108 101 $word=pack("C*",ascii_character_numbers);
$word = pack("C*",115, 97, 109, 112, 108, 101); # То же самое
print "$word\n",
sample
А вот как превратить HAL в IBM: $hal = "HAL";
@ascii = unpack("C*", $hal);
foreach $val (@ascii) {
$val++; # Увеличивает каждый ASCII - код на 1
$ibm = pack("C*), @ascii);
print "$ibm\n"; # Выводит "IBM'
Функция ord возвращает числа oт 0 до 255. Этот диапазон соответствует типу
данных unsigned char языка С.
> Смотри также ----------------------------
Описание функций chr. ord, printf, sprintf, pack и unpack в perlfunc(1).