2016-09-23 87 views
1

我收到此错误,无法理解为什么会发生这种情况。当我跳到另一个子程序时会发生这种情况。也许我需要了解一下Mojolicious为什么发生这种情况。Mojolicious:无法在未定义的值上调用方法“渲染”

这里是我的程序的源代码:

#!/usr/bin/perl 

use Mojolicious::Lite; 

get '/' => sub { &start_home; }; 

app->start; 

sub start_home { 
    my $d = shift; 
    my $something = $d->param('something'); 
    ### Do things with $something.... etc.. etc.. 
    &go_somewhere_else; ### Go somewhere else 
} 

sub go_somewhere_else { 
my $c = shift; 
$c->render(text => "Hello World!"); 
### End of program 
} 

我在传递一个值来渲染,有一个价值 - 它为什么会说这是不确定的?我的理解是,只有在跳转到子例程并尝试渲染输出时才会发生这种情况。

我的操作系统是Windows,我正在使用Strawberry Perl。

回答

3

您需要将上下文对象$c/$d传递给第二个函数。 未定义的值是您的$cgo_somewhere_else,因为您在没有参数的情况下调用它。

最初,为了使其工作,请执行此操作。

sub start_home { 
    my $d = shift; 
    my $something = $d->param('something'); 

    go_somewhere_else($d); 
} 

您现在已经传递上下文,你叫$d(这不是常规的名称),其他功能,并警告将消失。

这是因为形式&subname;没有括号()使得@_(这就是函数的自变量列表)可用的go_somewhere_else里面,而是因为你shift$d关闭,@_现在是空的,因此你$cgo_somewhere_elseundef

或者,您也可以将shift更改为@_。但请,不要那样做

sub start_home { 
    my ($d) = @_; 
    my $something = $d->param('something'); 

    &go_somewhere_else; 
} 

还有更多的事情奇怪,几乎错在这里的地步。

get '/' => sub { &start_home; }; 

您是currying的的start_home功能,但你实际上并没有增加其他参数。我上面解释了为什么这个工作。但这并不好。事实上,这是令人困惑和复杂的。

相反,您应该为路线使用代码参考。

get '/' => \&start_home; 

里面的start_home,你应该打电话给你的上下文$c因为是惯例。您也不应使用符号&表示法来调用函数。这改变了你绝对不想要的方式。

sub start_home { 
    my $c = shift; 
    my $something = $c->param('something'); 

    # ... 
    go_somewhere_else($c); 
} 

要了解更多关于函数调用如何在Perl中工作的信息,请参考perlsub

+0

@Eugen你的编辑不正确。第一个代码块的整个想法是'@ _'在函数中是空的,所以绝对不需要传递它。我在下面的段落中解释。我回滚了你的编辑。 – simbabque

+0

在这种情况下,第一个和第二个示例的工作方式不同。如果'start_home'获得两个或更多参数,第一个示例将丢弃所有参数,但第二个参数将通过它们。在第一个例子中,通过“@ _”直接显示了仅在第一个参数处的示例之间的区别。 –