【问题标题】:Creating recursive template blocks in Mojolicious在 Mojolicious 中创建递归模板块
【发布时间】:2014-10-08 10:43:15
【问题描述】:

我想在 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"] )

【问题讨论】:

    标签: perl mojolicious


    【解决方案1】:

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

    % my $block; $block = begin

    但是会产生内存泄漏,因为 $block 现在是一个循环引用,当它超出范围时 perl 无法删除。从 perl 5.16 开始,您可以在匿名 sub 中使用 __SUB__ 关键字来获取对该子例程的引用。所以这很简单

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

    如果你想在 perl

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

    【讨论】:

    • 非常感谢您提供出色的解决方案和出色的解释!
    • 是否可以使用Scalar::Util 中的weaken() 函数来避免循环引用的内存泄漏?
    猜你喜欢
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 2014-11-26
    • 2018-03-01
    • 1970-01-01
    • 2021-09-06
    相关资源
    最近更新 更多