8

我需要能够在 Mojolicious::Lite 应用程序中编写和调用我自己的子例程。但是,执行此操作的直观方法似乎不起作用。我给一个比我有更多 Mojolicious 经验的同事发了电子邮件,他给我发了以下代码:

#!/usr/bin/env perl
use Mojolicious::Lite;

# Documentation browser under "/perldoc"
plugin 'PODRenderer';

get '/' => sub {
  my $self = shift;
  $self->render('index');
};

sub factorial {
    my $n = shift;
    return $n ? $n * factorial($n - 1) : 1;
}

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!

Five factorial: <%= main::factorial(5) %>

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body><%= content %></body>
</html>

但是当我运行它时,它告诉我当我调用一个未定义的子例程时:

未定义的子例程 &main::factorial 在模板 index.html.ep 处调用,来自 DATA 部分第 5 行,第 32 行。

我花了很多时间处理这段代码,并尝试了不同的方法来让它工作,但到目前为止,唯一让它正常运行的是当子例程在@@ xxx.html 的范围内定义时。 ep的。我已经在 stackoverflow 上搜索/搜索了“Mojolicious::Lite 中的用户定义子例程”和其他类似查询。似乎什么都没有出现。我对文档的搜索也被证明是徒劳的。这似乎应该是一个简单的任务,但我有点卡住了。任何帮助,将不胜感激。

4

2 回答 2

6

正如 PerC 已经提到的,助手是向模板添加行为(或访问行为)的首选机制。既然他已经展示了那个例子,我只想补充一点,你可以通过做这样的事情来混合两者(我正在删除 pod 渲染器插件,你不需要它)。

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
  my $self = shift;
  $self->render('index');
};

sub factorial {
    my $n = shift;
    return $n ? $n * factorial($n - 1) : 1;
}

helper factorial => sub { shift; factorial(@_) };

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!

Five factorial: <%= factorial(5) %>

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body><%= content %></body>
</html>
于 2014-04-09T02:53:38.110 回答
5

如果您将 sub 重新加工成帮助程序,则可以从模板(或控制器)中访问它。

#!/usr/bin/env perl
use Mojolicious::Lite;

helper factorial => sub {
  my ($self, $n) = @_;
  return $n ? $n * $self->factorial($n - 1) : 1;
};

get '/' => 'index';

app->start;

__DATA__

@@ index.html.ep

Five factorial: <%= factorial(5) %>

运行应用程序给出(减去日志记录):

$ perl app.pl get /
Five factorial: 120
$

更新

这既不会回答您的问题,但会为您提供另一种选择。

我不知道您为什么喜欢从模板中调用 main 中的 sub 的背景。在我看来,模板(或我喜欢的视图)应该只呈现数据,而不是尝试计算/处理数据,这是模型(或控制器)的工作。由于控制器中的数据与模板中的数据相同(甚至更多),为什么不调用控制器中的 sub 并将结果传递给模板呢?结果可以是任何 Perl 数据结构,因此您不限于标量。

此外,当您将Mojolicious::Lite应用程序发展为完整的应用程序时,将不再有用package main(它只是一个调用您的 main 的小应用程序package MyApp)。这使得从模板调用通用 subs 的整个想法更不可行。

这是阶乘应用程序的另一个示例,其中计算在控制器中完成:

#!/usr/bin/env perl
use Mojolicious::Lite;

sub factorial {
  my $n = shift;
  return $n ? $n * factorial($n - 1) : 1;
}

get '/' => sub {
  my $self = shift;
  $self->render('index', result => factorial(5));
};

app->start;

__DATA__

@@ index.html.ep

Five factorial: <%= $result %>
于 2014-04-08T20:50:03.093 回答