【问题标题】:How to detect array type in Template toolkit? [closed]如何检测模板工具包中的数组类型? [关闭]
【发布时间】:2014-07-17 18:03:08
【问题描述】:

我需要在模板工具包中为数组类型的附件检测一些变量。 有最佳做法吗?

【问题讨论】:

  • 我不明白。您能否举例说明您正在努力实现的目标,以及您尝试过但没有成功的事情?
  • TT模板文件中有变量:[% var %]。我需要检测这个变量的类型(数组与否)。

标签: perl types template-toolkit


【解决方案1】:

在将数据传递给模板之前,控制器应验证您的数据。您的数据采用什么格式应该毫无疑问。

也就是说,检查这一点最有用的方法就是测试array 的大小:

[% IF var.size %]


[% END %]

【讨论】:

  • 如果数组为空,那么测试大小会导致假阴性。
  • 如果数组只有一个元素怎么办?它也返回 1。
  • 另外,scalar.size 将返回 1,hashref.size 将返回键/值对的数量。
  • 关于我概述的问题,可以通过覆盖标量和散列大小虚拟方法以始终返回 undef 即$Template::Stash::SCALAR_OPS->{ size } = sub { undef }; $Template::Stash::HASH_OPS->{ size } = sub { undef }; 来规避它们,然后测试 var.size 的结果是否已定义,即[% IF var.size.defined; 'ARRAY'; END %].
  • @bibimij scalar 和 hashref 是描述其数据类型的伪变量的名称。我用它们来表达我的观点,即[% hashref = { }; hashref.size %]。如果您阅读了我的答案,则可以通过定义自己的虚拟方法来解决您的问题。我定义了一个通用的 ref ,但您可能更喜欢定义一个 is_array() 。
【解决方案2】:

可以定义一个自定义虚拟方法,该方法返回所提供变量的 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

【讨论】:

  • 感谢分享,克里斯。我仍然坚持我最初的断言,即 OP 的问题可能是他以超出其最佳实践的方式使用模板的症状。一个人的数据格式对于需要检查 ref 类型的级别来说不应该是一个谜,如果它是控制器或模型中的缺陷。不过,感谢您分享此高级功能。 +1
  • 我完全同意,多年来使用模板工具包,我从来不需要在内部检测 ref 类型。
  • 最佳实践是一方面,通常我认为是的,但另一方面还有一些边缘情况,这并不一定意味着可以使用它的糟糕实践恕我直言。现在的最佳实践,不一定是 5 年后的最佳实践,所以最佳实践实际上并不总是最佳实践。尽管大多数人猜测 90% 的情况是这样,但这可能取决于具体情况。无论如何,我看到/意识到我主要赞成您的解决方案,我的意思是通常表示我接受,而不是否认您的解决方案。例如。解决方法的需要可能源于所用平台的一个小缺点。
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 2015-02-06
相关资源
最近更新 更多