цикл for для шаблона Text :: Template - PullRequest
1 голос
/ 06 мая 2011

Я пытаюсь использовать 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]: элемент1 item1 item2 Но вместо этого он печатает массив [0]: item1

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

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

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

Ответы [ 2 ]

1 голос
/ 06 мая 2011
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 %>

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

0 голосов
/ 06 мая 2011

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

{ 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, как правило, довольно хорошая, и ее стоит прочитать, вы пропустите ее, когда будете работать на других языках.

...