Отступы во встроенных документах

Проблема

При использовании механизма создания длинных строк (встроенных документов) текст должен выравниваться вдоль левого поля; в программе это неудобно. Требуется снабдить отступами текст документа в программе, но исключить отступы из окончательного содержимого документа.

Решение

Воспользуйтесь оператором 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///



2013-09-10 17:05:19

Proverte kod v komentariyah gde pro list tam oshibki detskie




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: