Цикл for для шаблона Text::Template

Я пытаюсь использовать perl Text::Template для коротких шаблонов и пока не смог заставить его перебирать массив.

Вот короткая тестовая программа, которую я написал, чтобы продемонстрировать, что я пытаюсь сделать:

#!/usr/bin/perl
use Text::Template;
my $template = Text::Template->new(TYPE => 'STRING', SOURCE => <<'__EOT__');
array[0]: { $array[0] }
{ foreach my $i (@array) { }
 {$i}
}
__EOT__
print $template->fill_in(HASH => { array => [qw(item1 item2)]});

В соответствии с руководством Text::Template я ожидал, что это будет печатать: массив [0]: item1 item1 item2 Но вместо этого он печатает массив [0]: item1

(т.е. вывод первой строки вне цикла и пустой строки).

Я не смог найти в Интернете ни одного примера, когда кто-нибудь действительно использовал цикл внутри шаблона, хотя в документации сказано, что он должен "просто работать".

Что мне не хватает?

2 ответа

my $template = Text::Template->new(TYPE => 'STRING', SOURCE => <<'__EOT__',  DELIMITERS => [qw(<% %>)],);

Выберите разные разделители. Документация советует вам делать это несколько раз по разным причинам, в основном из-за того, что с ними легче работать, потому что в Perl-коде также используется {} брекеты. Это также говорит:

Поскольку синтаксический анализ шаблонов упрощается благодаря отсутствию обратной косой черты, использование альтернативных разделителей может ускорить процесс синтаксического анализа на 20-25%. Это показывает, что мой первоначальный выбор {и} был очень неудачным.

Просто {$i} не работает здесь, потому что это в пустом контексте. В документации сказано:

Результат последнего выполненного оператора будет оцениваться в скалярном контексте; Результатом этого оператора является строка, которая вставляется в шаблон вместо самого фрагмента программы.

Перепишите его с помощью $OUT переменная:

<% foreach my $i (@array) {
    $OUT .= $i
} %>

В документации сказано:

Все, что вы добавляете в эту переменную, будет отображаться в выходных данных шаблона. Также, если вы используете $OUT во фрагменте программы, нормальное поведение замены фрагмента его возвращаемым значением отключается; вместо этого фрагмент заменяется значением $OUT.

<% $OUT .= $_ for @array %>

Тот же результат, но короче.

Пара экспериментов показывает, что это:

{ stuff }

Превращается (эффективно) во что-то вроде этого псевдоперла:

my $x = eval(stuff);
$template =~ s/{ stuff }/$x/;

Таким образом, "материал" должен быть выражением, чтобы он возвращал что-то в шаблон. Ваш "материал" является foreach цикл, который не имеет значения, поэтому ваш шаблон не делает ничего интересного.

Если вы посмотрите на тесты для Text::Template (всегда заходите в набор тестов для примеров, наборы тестов для пакетов CPAN неоценимы для изучения того, как все работает), вы увидите такие вещи:

{ $t = ''; foreach $n (1 .. 20) { $t .= $n . ' ' } $t }

Обратите внимание на способ $t используется. Это означает, что вы хотите что-то более похожее на этот шаблон:

array[0]: { $array[0] }
{ $t = ''; foreach my $i (@array) { $t .= "\t$i\n" } }

Там также $OUT специальная переменная, которая может заменить $t выше. Документация для пакетов CPAN, как правило, довольно хорошая и заслуживает прочтения, вы пропустите ее, когда будете работать на других языках.

Другие вопросы по тегам