我想在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"] )
答案 0 :(得分:8)
要在表达式中使用变量,需要在表达式之前声明此变量。所以,这将有效:
% my $block; $block = begin
但是会产生内存泄漏,因为$ block现在是一个循环引用,当它超出范围时perl无法删除。从perl 5.16开始,你可以在anonymous sub中使用__SUB__关键字来获取对这个子例程的引用。所以这就像
一样简单% use v5.16;
% my $block = begin
...
__SUB__->($item)
...
% end
如果你想在perl上运行你的代码&lt; 5.16您可以使用替代方法来避免内存泄漏。只是不要使用闭包,而是将对块的引用作为参数传递
% my $block = begin
% my ($block, $menu) = @_;
...
%= $block->($block, $item);
...
% end
%= $block->( $block, ["a", ["ba", "bb"], "c"] )