在Mojolicious中创建递归模板块

时间:2014-10-08 10:43:16

标签: perl 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"] )

1 个答案:

答案 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"] )