1

我了解 BEGIN 在主程序之前执行。问题是:

  • 谈论 PGSI 应用程序时的主程序是什么——或者更好
  • 什么时候在 PGSI 应用程序中执行 BEGIN 块?
  • 它是不同的plackup还是Starman和喜欢?
  • 中间件呢?什么时候有多个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::CgiApp1和 my app.pgsi

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

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

或者一个简单的

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

1 回答 1

4

BEGIN块在编译阶段立即执行,编译器看到块的结尾。

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

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

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

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

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

于 2014-01-17T12:05:10.013 回答