Выбор значения по умолчанию
Проблема
Требуется закрепить за скалярной переменной значение по умолчанию, но лишь в том случае, если оно
не было задано ранее. Довольно часто требуется, чтобы стандартное значение переменной жестко
кодировалось в программе, но его можно было переопределить из командной строки или переменной окружения.
Решение
Воспользуйтесь оператором || или ||=, работающим как со строками, так и с числами:
# Использовать $b, если значение $b истинно, и $с в противном случае
$а = $b || $с;
# Присвоить $х значение $у, но лишь в том случае,
# если $х не является истинной
$х ||= $у;
Если ваша переменная может принимать значения 0 или "0", воспользуйтесь функцией
defined:
# Использовать $b, если значение $b определено, и $с в противном случае
$а = defined($b) ? $b : $с;
Комментарий
Главное отличие между этими двумя приемами (defined и ||) состоит, прежде всего, в том, что именно
проверяется — определенность или истинность. В мире Perl три определенных значения являются ложными: 0, "0" и "".
Если ваша переменная содержит одну из этих величин, но вы не хотите изменять ее, || не подойдет — приходится
выполнять неуклюжие проверки с defined. Часто бывает удобно организовать программу так, чтобы принималась в
расчет истинность или ложность переменных, а не их определенность.
В отличие от других языков, где возвращаемые значения ограничиваются 0 и 1, оператор || Perl обладает
более интересным свойством: он возвращает первый (левый) операнд, если тот имеет истинное значение; в противном
случае возвращается второй операнд. Оператор && ведет себя аналогично (для второго выражения), но этот факт
используется реже. Для операторов несущественно, что представляют собой их операнды — строки, числа или ссылки;
подойдет любое скалярное значение. Они просто возвращают первый операнд, из-за которого все выражение становится
истинным или ложным. Возможно, это расходится с возвращаемым значением в смысле булевой алгебры, но такими
операторами удобнее пользоваться.
Это позволяет установить значение по умолчанию для переменной, функции или более длинного выражения
в том случае, если первый операнд не подходит. Ниже приведен пример использования ||, в котором $fоо
присваивается либо $bаr, либо, если значение $bаr ложно, — строка "DEFAULT VALUE":
$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 $<";
Оператор && работает аналогично; он возвращает первый операнд, если этот операнд ложен. В противном случае
возвращается второй операнд. Поскольку ложные значения представляют интерес существенно реже, чем истинные,
это свойство используется не так часто.
Оператор присваивания || = выглядит странно, но работает точно так же, как и остальные операторы
присваивания. Практически для всех бинарных операторов Perl $VAR ОР = VALUE означает $VAR = $VAR OP VALUE; например,
$а += $b – тоже, что и $а = $а + $b. Следовательно, оператор ||= может использоваться для присваивания
альтернативного значения переменной. Поскольку || выполняет простую логическую проверку (истина или ложь),
него не бывает проблем с неопределенными значениями, даже при использовании ключа -w.
В следующем примере = присваивает переменной $starting_point значение "Greenwich", если оно не было
задано ранее. Предполагается, что $starting_point не принимает значений 0 или "0", а если принимает — то такие
значения должны быть заменены:
$starting_point ||= "Greenwich"
В операторах присваивания || нельзя заменять оператором or, поскольку or имеет слишком низкий
приоритет. Выражение $а = $b or $с эквивалентно ($а = $b) or $c. В этом случае переменной $Ь всегда присваивается
$а, а это совсем не то, чего вы добивались.
Не пытайтесь распространить это любопытное применение || и || = со скалярных величин на массивы
и хэши. У вас ничего не выйдет, потому что левый операнд интерпретируется в скалярном контексте.
Приходится делать что-нибудь подобное:
@а = @b unless @a; # Копировать, если массив пуст
@а = @>b ? @b : @с; # Присвоить @Ь, если он не пуст, иначе @с
См. такжеОписание функций
defined и
exists
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|