Инструментарий шаблона Если в пустом массиве ref возвращает true, могу ли я сделать его ложным?

Итак, кажется, что если я даю набору инструментов шаблона ссылку на массив в качестве параметра

ARRAY_REF => \@array

а затем иметь следующий код в шаблоне

[% IF ( ARRAY_REF ) %]
  Do something
[% ELSE %]
  Do something else
[% END %]

Случай else никогда не срабатывает.

Замена кода параметра на

ARRAY_REF => @array ? \@array : undef;

кажется, решает проблему, однако мне было интересно, есть ли способ заставить инструментарий шаблона оценивать пустой массив (переданный по ссылке) как ложный, поскольку в моем проекте есть много случаев, когда я считаю, что это используется (как в шаблоне HTML pro это сработало, как и ожидалось).

Заранее всем спасибо за помощь.


person cjh    schedule 03.02.2011    source источник


Ответы (3)


Ваше ARRAY_REF будет истинным, потому что оно определено и будет истинным значением в Perl. Обычный подход состоит в том, чтобы проверить, что оно истинно и не пусто:

[% IF ARRAY_REF && ARRAY_REF.size %]
    Do something
[% ELSE %]
    Do something else
[% END %]

Скажите, что вы на самом деле имеете в виду, если попросить компьютер притвориться умнее, чем он есть на самом деле, это приведет к странным сюрпризам.

Вероятно, вы могли бы изменить представление ТТ о достоверности, но я не думаю, что вам понравится это или различные неприятные побочные эффекты, с которыми вы, вероятно, столкнетесь. Template Toolkit не HTML Template Pro, когда в Риме делают то, что делают римляне и все такое.

Лучше всего исправить свои шаблоны и рассматривать дополнительную работу как часть процесса переноса. Вы, вероятно, могли бы создать плагин, который будет делать за вас «истинные и непустые» вещи.

person mu is too short    schedule 03.02.2011
comment
Нужен ли первый тест? Кажется, просто выполнение [% IF ARRAY_REF.size %] не жалуется, когда нет такой вещи, как ARRAY_REF. - person cjh; 04.02.2011
comment
@suicideducky: Просто [% IF ARRAY_REF.size %] должно быть достаточно. Проверка его наличия перед вызовом .size является привычкой для всех других языков, с которыми я работаю. - person mu is too short; 04.02.2011
comment
@mu Я сам программист на C ++, поэтому у меня такая же привычка, просто когда я возился, я заметил, что perl, похоже, все равно, поэтому я подумал, что спрошу. Ваше здоровье. - person cjh; 04.02.2011
comment
@suicideducky: Perl заботится, Template Toolkit не волнует, C заботится, C++ заботится, JavaScript заботится, Ruby заботится, ... так что я тоже забочусь о том, чтобы все было проще. - person mu is too short; 04.02.2011
comment
@mu простите меня, если я ошибаюсь, но следующее: my $a; if($a.badsd){напечатать a.badsd\n;}; if($b.dudsa){print b.dudsa\n;}; кажется, работает нормально, печатая оба оператора печати. Вы говорили о perl с комбинацией use strict/warnings? - person cjh; 04.02.2011
comment
@suicideducky: моя $а; if($a-›badsd){print a-›badsd\n;}; if($b-›dudsa){print b-›dudsa\n;};, . предназначен для конкатенации строк (например, _ в Template Toolkit или + в JavaScript или C++), тогда как -> такой же, как в C++. И, да, я всегда use strict;use warnings;, даже если это всего лишь одноразовый быстрый хак, точно так же, как я всегда -Wall -Werror с gcc при работе на C или C++. - person mu is too short; 04.02.2011
comment
@mu Глупая ошибка с моей стороны, не могу поверить, что использовал не того оператора. Большое спасибо, что нашли время, чтобы прояснить это :) - person cjh; 07.02.2011
comment
@suicideducky: Не беспокойтесь, моя обычная ошибка оператора сбивает с толку. и _ в Perl при работе с TT. - person mu is too short; 07.02.2011

Я думаю, что .size это то, что вам нужно.

perl -MTemplate -le '$t = Template->new; $t->process(\"[% \"O HAI\" IF arrayref.size %]", { arrayref => [] })'

perl -MTemplate -le '$t = Template->new; $t->process(\"[% \"O HAI\" IF arrayref.size %]", { arrayref => [1] })'
O HAI

Я бы также предложил, чтобы ссылка на пустой массив была истинной в простом Perl.

perl -le '$abc = []; print "true" if $abc'
true

И когда вы делаете это напрямую, это более очевидно (возможно), почему это должно быть очевидно…

perl -le 'print "true" if []'
true
person Ashley    schedule 03.02.2011
comment
Тоже правильно, но, к сожалению, я не могу принять два ответа. Спасибо большое однако :) - person cjh; 04.02.2011

Протестируйте, обратившись к 1-му элементу массива:

[% IF ( ARRAY_REF.0 ) %]
person tadmc    schedule 03.02.2011
comment
Это не удастся даже с огромным массивом, если первый элемент массива ref имеет значение false. :( - person Ashley; 03.02.2011