繁体   English   中英

在Perl的Template Toolkit中访问作为匿名哈希的数组项

[英]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.nameby_name

一旦准备就绪,剩下的就是一个简单的循环。 我们迭代by_adminsort 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 strictuse warnings

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM