Perl的app.psgi中的BEGIN块

时间:2014-01-17 11:45:04

标签: perl psgi

我知道BEGIN是在主程序之前执行的。问题是:

  • 在谈论PGSI应用程序时,主程序是什么 - 或者更好
  • 什么时候会在PGSI app中执行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;
}

将执行的顺序是多个BEGIN阻止My::CgiApp1app.pgsi中定义的内容?

从上面的PSGI应用程序的角度来看,使用的主要区别是什么:

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

或简单的

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

1 个答案:

答案 0 :(得分:4)

编译阶段执行

BEGIN块,编译器立即看到块结束。

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

请记住,use语句在隐藏的require块中基本上是BEGIN,因此在您的情况下,编译器将处理主程序,尽快执行YAML::LoadFile可以看到BEGIN块的右括号。然后它将继续编译程序,直到use My::CgiApp1,它将暂停处理主程序并开始编译My/CgiApp1.pm

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

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

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