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