Интерполяция функций и выражений в строках
Проблема
Требуется интерполировать вызов функции или выражение, содержащиеся в строке.
По сравнению с интерполяцией простых скалярных переменных это позволит конструировать более сложные шаблоны.
Решение
Выражение можно разбить на отдельные фрагменты и произвести конкатенацию:
$answer = $var1.func().$var2; # Только для скалярных величин
Также можно воспользоваться неочевидными расширениями @{[LIST EXPR]} или ${\(SCALAR EXPR)}:
$answer = "STRING @{[LIST EXPR]} MORE STRING";
$answer = "STRING ${\(SCALAR EXPR)} MORE STRING";
Комментарий
В следующем фрагменте продемонстрированы оба варианта. В первой строке выполняется конкатенация,
а во второй — фокус с расширением:
$phrase = "I have ".($n + 1)."guanacos.";
$phrase = "I have ${\($n + 1)} guanacos.";
В первом варианте строка-результат образуется посредством конкатенации более мелких строк; таким образом,
мы добиваемся нужного результата без интерполяции. Функция
print фактически выполняет конкатенацию
для всего списка аргументов, и, если вы собираетесь вызвать print $phrase, можно было бы просто написать:
print "I have ", $n + 1 . "guanacos.\n";
Если интерполяция абсолютно неизбежна, придется воспользоваться вторым вариантом, изобилующим знаками препинания.
Только символы @, $ и \ имеют особое значение в кавычках и обратных апострофах. Как и в случаях с
m// и
s///,
синоним qx() не подчиняется правилам расширения для кавычек, если в качестве ограничителя использованы апострофы!
$home = qx'echo home is $HOME' возьмет переменную $НОМЕ из командного интерпретатора, а не из Perl! Итак, единственный
способ добиться расширения произвольных выражений — расширить ${} или @{}, в чьих блоках присутствуют ссылки.
Однако вы можете сделать нечто большее, чем просто присвоить переменной значение, полученное в результате интерполяции.
Так, в следующем примере мы конструируем строку с интерполированным выражением и передаем результат функции:
some_func("What you want is @{[ split /:/, $rec ]} items");
Интерполяция может выполняться и во встроенных документах:
die "Couldn't send mail" unless send_rnail(<<"EOTEXT", $target);
To: $naughty
Frоm: Your bank
Cc: ${ [get_manager_list($naughty)] }
Date: @{[ do { my $now = 'date'; chomp $now; $now} ]} (today)
Dear $naughty,
Today, you bounced check number @{[ 500 + int rand(100) ]} to us.
Your account is now closed.
Sincerely,
the management
EOTEXT
Расширение строк в обратных апострофах ('') оказывается особенно творческой задачей, поскольку оно часто
сопровождается появлением ложных символов перевода строки. Создавая блок в скобках за @ в разыменовании
анонимного массива @{[ ]}, как это было сделано в последнем примере, вы можете создавать закрытые (private) переменные.
В версии 5.004 Perl в выражении ${ \EXPR } значение EXPR ошибочно вычислялось в списковом, а не скалярном контексте.
Ошибка была исправлена в версии 5.005.
См. также
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|