[英]Access an array item that is an anonymous hash in Template Toolkit in Perl
我将这段代码作为控制器中foreach循环的一部分:
my $gr = My::Model::Group->new(id => $gra->gr_id);
$gra = My::Model::Group::Admin->new(id => $gra->id);
push(@$groups, {$gr => $gra});
在@ $ groups数组中,我想存储匿名哈希,其中的关键元素是组对象,而值元素是该组对象的管理员。 然后在模板中,我想显示管理员可以登录的不同组的列表,为此我有以下代码:
[%- FOREACH gr IN groups -%]
<li><input type="radio" name="group" value="[% gr.id %]">[% gr.name %]</input></li>
[%- END -%]
我知道p IN合作伙伴不正确,而是向您展示我想要实现的目标。 关于模板代码有什么建议吗?
您将需要对代码进行大量重做才能使其成为可能。
Perl哈希中的键是字符串 ,而不是标量。 使用任何不是一个字符串作为哈希键(例如, $gr
在表达{ $gr => $gra }
将导致它被字符串化,就好像你已经插入它变成一个字符串或打印它。除非您在My::Model::Group
对象上显式重载了""
运算符,否则该键最终将作为文字字符串存储在以下行中:
"My::Model::Group=HASH(0x1234567890)"
该字符串不能转换回原始对象-实际上,原始对象可能在超出范围后立即被垃圾回收,因此它根本不存在。
考虑将其存储为数组引用,例如
push @$groups, [$gr, $gra];
duskwuff已经在他们的答案中说明 ,当对象被序列化时,您不能将它们用作哈希键,并且会失去对象的特性。 我的答案基于此。
假设您有一个数组数组,每个内部数组都包含一对对象。 我创建了Moo类进行说明。
package My::Model::Group;
use Moo;
has [qw/id name/] => ( is => 'ro' );
package My::Model::Group::Admin;
use Moo;
has [qw/id name/] => ( is => 'ro' );
package main;
my $groups = [
[
My::Model::Group->new( id => 1, name => 'group1' ) =>
My::Model::Group::Admin->new( id => 1, name => 'foo' )
],
[
My::Model::Group->new( id => 2, name => 'group2' ) =>
My::Model::Group::Admin->new( id => 1, name => 'foo' )
],
[
My::Model::Group->new( id => 3, name => 'group3' ) =>
My::Model::Group::Admin->new( id => 1, name => 'bar' )
],
[
My::Model::Group->new( id => 4, name => 'group4' ) =>
My::Model::Group::Admin->new( id => 1, name => 'foo' )
],
];
有四对。 两个管理员,四个小组。 其中三个组属于foo admin,另一个属于bar 。 现在让我们看一下模板。
use Template;
my $tt = Template->new();
$tt->process( \*DATA, { groups => $groups }, \my $output )
or die $tt->error;
print $output;
__DATA__
[%- FOREACH item IN groups -%]
[%- DEFAULT by_admin.${item.1.name} = [] -%]
[%- by_admin.${item.1.name}.push(item.0) -%]
[%- END -%]
[%- FOREACH admin IN by_admin.keys.sort -%]
[%- FOREACH group IN by_admin.$admin -%]
[%- admin %] -> [% group.id %]
[%- END -%]
[%- END -%]
显然相关的部分是DATA
部分。 我们需要将数组数据结构重组为具有管理员的哈希,然后将每个组分类到一个管理员插槽中。
我们不需要创建by_admin
变量。 它将在全局隐式创建。 但是我们确实需要为$by_admin->{$item[0]->name}
设置默认值(为了易于理解,我现在正在使用Perl语法)。 似乎Template Toolkit不知道自动生存能力 ,并且DEFAULT
关键字类似于Perl中的//=
赋值运算符 。
然后,我们可以push
的第一个元素item
到我们刚刚创建的数组引用与键(如果还不存在的话)的哈希ref元素内item.1.name
内by_name
。
一旦准备就绪,剩下的就是一个简单的循环。 我们迭代by_admin
的sort
keys
,然后迭代该键后面的数组ref。
这是输出:
bar -> 3
foo -> 1
foo -> 2
foo -> 4
最好不要在模板中而是在控制器中进行预处理。 作为正常的Perl代码,它应该更易于阅读。
my %by_admin;
for my $group (@$groups) {
push @{ $by_admin{ $group->[1]{name} } }, $group->[0];
}
请注意,为简洁起见,我省略了use strict
和use warnings
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.