2014-10-08 60 views
2

我想在Mojolicious中创建一个递归模板块以从嵌套数组生成复杂菜单。在Mojolicious中创建递归模板块

理想地,阵列["a", ["ba", "bb"], "c"]将导致此嵌套列表:

<ul> 
    <li>a</li> 
    <li> 
     <ul> 
      <li>ba</li> 
      <li>bb</li> 
     </ul> 
    </li> 
    <li>c</li> 
</ul> 

下面的代码不工作,因为块是匿名的子程序而不能使用自己的引用:

% my $block = begin 
    % my $menu = shift; 
    <ul> 
    % foreach my $item (@{$menu}){ 
    % if(ref($item) eq 'ARRAY') { 
     <li> 
     %= $block->($item); 
     </li> 
    % } else { 
     <li><%= $item %></li> 
    % } 
    % } 
    </ul> 
% end 
%= $block->(["a", ["ba", "bb"], "c"]) 

回答

7

要在需要在表达式之前声明该变量的表达式中使用变量。因此,这将工作:

% my $block; $block = begin

但会产生内存泄漏,因为$块现在是一个循环引用,这perl的无法删除时,它会走出去的范围。自从perl 5.16以后,你可以在匿名sub中使用__SUB__关键字来获得对这个子程序的引用。因此,这将是一样简单

% use v5.16; 
% my $block = begin 
    ... 
     __SUB__->($item) 
    ... 
% end 

如果你想在Perl的< 5.16运行你的代码,你可以用另一种方式来避免内存泄漏。只要不使用封闭,而是通过参考块作为参数

% my $block = begin 
    % my ($block, $menu) = @_; 
    ... 
     %= $block->($block, $item); 
    ... 
% end 
%= $block->($block, ["a", ["ba", "bb"], "c"]) 
+0

@ikegami,谢谢,我已经更新了我的答案 – 2014-10-09 03:58:44

+0

非常感谢你的伟大的解决方案(S)和优异的解释! – PJVolders 2014-10-09 11:47:50