Как определить тип массива в наборе инструментов Template?

Мне нужно определить некоторую переменную для принадлежности к типу массива в наборе инструментов Template. Существуют ли лучшие практики?


person bibimij    schedule 28.05.2014    source источник
comment
Я не понимаю. Можете ли вы привести пример того, чего вы пытаетесь достичь, и, возможно, что-то, что вы пробовали, но не сработало?   -  person RobEarl    schedule 28.05.2014
comment
В файле шаблона ТТ есть переменная: [% var %]. Мне нужно определить тип этой переменной (массив или нет).   -  person bibimij    schedule 28.05.2014


Ответы (2)


Ваши данные должны быть проверены контроллером ДО того, как они будут переданы в шаблон. Не должно быть никакой тайны, в каком формате находятся ваши данные.

Тем не менее, самый полезный способ проверить это — просто протестировать array< /a> размер:

[% IF var.size %]


[% END %]
person Miller    schedule 28.05.2014
comment
Если массив пуст, проверка размера приведет к ложноотрицательному результату. - person Chris; 29.05.2014
comment
Что делать, если массив состоит из одного элемента? Он также возвращает 1. - person bibimij; 29.05.2014
comment
Кроме того, scalar.size вернет 1, а hashref.size вернет количество пар ключ/значение. - person Chris; 29.05.2014
comment
Что касается проблем, которые я описал, их можно обойти, переопределив виртуальные методы скалярного размера и размера хэша, чтобы они всегда возвращали undef, т. е. $Template::Stash::SCALAR_OPS->{ size } = sub { undef }; $Template::Stash::HASH_OPS->{ size } = sub { undef };, а затем проверили, что результат var.size определен, т. е. [% IF var.size.defined; 'ARRAY'; END %]. - person Chris; 29.05.2014
comment
@Chris, scalar.size и hashref.size — что вы имеете в виду? - person bibimij; 29.05.2014
comment
@bibimij scalar и hashref — это имена псевдопеременных, которые описывают их типы данных. Я использовал их, чтобы выразить свою точку зрения, т.е. [% hashref = { }; hashref.size %]. Если вы читаете мой ответ, ваша проблема может быть решена путем определения собственного виртуального метода. Я определил общий ref, но вы можете предпочесть определить is_array(). - person Chris; 29.05.2014
comment
@ Крис, о, хорошо. Я попробую. Спасибо! - person bibimij; 29.05.2014
comment
См. мой ответ на stackoverflow.com/questions/51539514/ для действительно работающего решения (не похоже на этот ответ). - person Guido Flohr; 13.08.2018

Можно было бы определить собственный виртуальный метод, который возвращает тип ref предоставленной переменной. Грубый пример:

#!/usr/bin/perl
use strict;
use warnings;
use Template;
use Template::Stash;

$Template::Stash::SCALAR_OPS->{ ttref } = \&ttref;
$Template::Stash::LIST_OPS  ->{ ttref } = \&ttref;
$Template::Stash::HASH_OPS  ->{ ttref } = \&ttref;

my $t = Template->new( );

$t->process( \*DATA, { vars => [ 1, [ ], { } ] } );

sub ttref
{
    return ref $_[0];
}

__DATA__
[% FOREACH var IN vars -%]
ref type of [% var %] is [% var.ttref %]
[% END %]

Выход:

ref type of 1 is 
ref type of ARRAY(0x9cfbd0) is ARRAY
ref type of HASH(0x9cfc00) is HASH
person Chris    schedule 28.05.2014
comment
Спасибо, что поделились этим, Крис. Я по-прежнему придерживаюсь своего первоначального утверждения о том, что вопрос ОП, вероятно, является симптомом того, что он использует шаблоны, выходящие за рамки их передовой практики. Формат данных не должен быть загадкой на уровне, необходимом для изучения типов ссылок, и если это так, то в контроллере или модели есть изъян. Тем не менее, спасибо, что поделились этой расширенной функцией. +1 - person Miller; 30.05.2014
comment
Я полностью согласен, за годы использования инструментария шаблонов мне никогда не приходилось определять тип ссылки внутри. - person Chris; 30.05.2014
comment
лучшая практика - это одна сторона, обычно я предполагаю, что да, но с другой стороны есть еще несколько крайних случаев, которые не обязательно подразумевают плохую практику imho, для которой ее можно использовать. Лучшая практика сейчас не обязательно должна быть лучшей практикой через 5 лет, поэтому лучшая практика на самом деле не всегда является лучшей практикой. Хотя в большинстве случаев в 90% случаев это так, но это может зависеть от случая. В любом случае, я вижу/понимаю, что в основном проголосовал за ваше решение выше, я имею в виду, что в целом я принимаю, а не отрицаю ваше решение. Например. необходимость обходного пути может быть связана с небольшим недостатком используемой платформы. - person FantomX1; 25.03.2021