簡體   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