2014-01-17 32 views
1

我知道BEGIN在主程序之前执行。这些问题是:Perl的BEGIN块在app.psgi

  • 谈论一个PGSI应用程序时,什么是主程序 - 或更好
  • 时,将执行在PGSI应用BEGIN块?
  • 这是不同的plackupStarman和?
  • 中间件怎么样 - 何时有多个 BEGIN块?

app.psgi

use Modern::Perl; 
use YAML; 
use Plack::Builder; 
use CGI::Emulate::PSGI; 

our($cfg); 

BEGIN { 
    $cfg = YAML::LoadFile("my.config"); 
} 

#old really __BIG__ cgi application - what uses many BEGIN blocks too... 
my $app1 = CGI::Emulate::PSGI->handler(sub { 
    use My::CgiApp1; 
    My::CgiApp1::executer->run(); 
}); 
my $app2 = sub { ... }; 

builder { 
    mount "/path1" => $app1; 
    mount "/"  => $app2; 
} 

在什么顺序将被执行多开始My::CgiApp1和我app.pgsi定义了什么块?

从鉴于上述PSGI应用程序的一点是什么使用的主要区别:

BEGIN { 
    $cfg = YAML::LoadFile("my.config"); 
} 

或简单

$cfg = YAML::LoadFile("my.config"); 

回答

4

BEGIN块期间编译相的立即结束时执行编译器会看到该块。

这意味着在主运行开始之前,每个BEGIN块仅执行一次,并且按编译器查看它们的顺序执行块。

请记住,一个use声明基本上是一个隐藏BEGINrequire,所以你的情况,编译器会尽快为BEGIN块的大括号被看作过程中的主要程序,执行YAML::LoadFile。然后它将继续编译该程序,直到use My::CgiApp1,它将暂停处理主程序并开始编译My/CgiApp1.pm

Perl现在将执行在遇到它时在此文件中找到的任何BEGIN块,并且类似地在任何其他use语句的情况下暂停处理。

只要任何use语句中指定的模块已完成编译,处理将在下一行代码的原始文件中继续。

所有这些发生在执行My::CgiApp1::executer->run之前,这是一个普通的语句,因此在运行时执行。