如何在Mojolicious :: Lite应用程序中使用我自己的子程序(全局)

时间:2014-04-08 17:37:45

标签: perl subroutine mojolicious mojolicious-lite

我需要能够在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>

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

  

未定义的子程序&amp; main :: factor在模板index.html.ep中从DATA第5行第32行调用。

我花了很多时间来处理这段代码,并尝试了不同的东西来使它工作,但到目前为止唯一让它正常运行的是当子程序在@的范围内定义时@ xxx.html.ep&#39; s。我已经用Google搜索/搜索了stackoverflow,以获取Mojolicious :: Lite&#34;中用户定义的子程序。和其他类似的查询。似乎没有出现任何事情。我对文档的搜索也证明是徒劳的。这似乎应该是一项简单的任务,但我有点卡住了。任何帮助,将不胜感激。

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:5)

如果您将子工作重新编入helper,则可以从模板(或控制器)中访问它。

#!/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并将结果传递给模板?结果可以是Perl数据结构,因此您不限于标量。

此外,当您将Mojolicious::Lite应用扩展为完整应用时,则无效 更长的有用package main(它只是一个调用主package MyApp的小应用程序)。这使得从模板调用泛型subs的整个想法更不用说前进了。

以下是阶乘app的另一个示例,其中计算在控制器中完成:

#!/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 %>