Отступы во встроенных документах
Проблема
При использовании механизма создания длинных строк (встроенных документов) текст должен выравниваться
вдоль левого поля; в программе это неудобно. Требуется снабдить отступами текст документа в программе, но исключить
отступы из окончательного содержимого документа.
Решение
Воспользуйтесь оператором s/// для отсечения начальных пропусков:
# Все сразу
($var = <<HERE_TARGET) =~ s/^\s+//gm;
далее следует
ваш текст
HERE_TARGET
# Или за два этапа
$var = <<HERE_TARGET;
далее следует
ваш текст
HERE_TARGET
$var =~ s/^\s+//gm;
Комментарий
Подстановка получается весьма прямолинейной. Она удаляет начальные пропуски из текста встроенного документа.
Модификатор /m позволяет символу ^ совпадать с началом каждой строки документа, а модификатор /g заставляет механизм
поиска повторять подстановку с максимальной частотой (то есть для каждой строки встроенного документа).
($definition = <<'FINISH') =~ s/^\s+//gm;
The five variations of camelids
are the familiar camel, his frieds
the llama and the alpaca, and the
rather less well-known guanaco
and vicuca.
FINISH
Учтите: во всех шаблонах этого рецепта используется модификатор \s, разрешающий совпадение с символами перевода строки.
В результате из встроенного документа будут удалены все пустые строки. Если вы не хотите этого, замените в шаблонах \s на [^\S\n].
В подстановке используется то обстоятельство, что результат присваивания может использоваться в левой стороне =~.
Появляется возможность сделать все в одной строке, но она работает лишь при присвоении переменной. При непосредственном
использовании встроенный документ интерпретируется как неизменяемый объект, и вы не сможете модифицировать его. Более того,
содержимое встроенного документа нельзя изменить без предварительного сохранения его в переменной.
Впрочем, для беспокойства нет причин. Существует простой обходной путь, особенно полезный при частом выполнении
этой операции. Достаточно написать подпрограмму:
sub fix {
my $string = shift;
$string =~ s/^\s+//gm;
return $string;
}
print fix(<<END"V");
Наш документ
END
# Если функция была объявлена заранее, скобки можно опустить:
print fix <<"END";
Наш документ
END
Как и во всех встроенных документах, маркер конца документа (END в нашем примере) должен быть выровнен по левому полю.
Если вы хотите снабдить отступом и его, в документ придется добавить соответствующее количество пропусков:
($quote = <<'FINISH') =~ s/^\s+//gm;
...we will have peace, when you and all you works have
perished--and the works of your dark master to whom you would
deliver us. You are a liar, Saruman, and a corrupter of men's
hearts. --Theoden in /usr/src/perl/taint.c
FINISH
$quote =~ s/\s+--/\n--; # Перенести на отдельную строку
Если эта операция выполняется с документами, содержащими программный код для
eval или просто выводимый текст, массовое
удаление всех начальных пропусков нежелательно, поскольку оно уничтожит отступы в тексте. Конечно, это
безразлично для eval, но не для читателей.
Мы подходим к следующему усовершенствованию — префиксам для строк, которые должны снабжаться отступами. Н
апример, в следующем примере каждая строка начинается с @@@ и нужного отступа:
if ($REMEMBER_THE_MAIN) {
$perl_main_C = dequote<<'MAIN_INTERPRETER_LOOP';
@@@ int
@@@ runops() {
@@@ SAVEI32(runlevel);
@@@ runlevel++;
@@@ while ( op = (*op->op_ppaddr)() );
@@@ TAINT_NOT;
@@@ return 0;
@@@ }
MAIN_INTERPRETER_LOOP
# При желании добавьте дополнительный код
}
См. такжеОписание оператора s///
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|