perl - Perl 中 BEGIN block 的作用是什么?

标签 perl

我知道 BEGIN block 是在 Perl 程序主体之前编译和执行的。如果您不确定,请尝试运行命令 perl -cw :

#!/ms/dist/perl5/bin/perl5.8

use strict;
use warnings;

BEGIN {
    print "Hello from the BEGIN block\n";
}

END {
    print "Hello from the END block\n";
}

我被告知,BEGIN block 的早期编译和执行可以让程序员确保在执行主程序之前任何所需的资源都可用。

因此,我一直在使用 BEGIN block 来确保数据库连接等内容已建立并可供主程序使用。同样,我使用 END block 来确保在程序终止之前所有资源都被关闭、删除、终止等。

经过今天早上的讨论,我想知道这是否是查看 BEGIN 和 END block 的错误方法。

Perl 中 BEGIN block 的预期作用是什么?

更新 1:刚刚发现 DBI 连接不起作用的原因。得到这个 Perl 小程序后:

use strict;
use warnings;

my $x = 12;

BEGIN {
    $x = 14;
}

print "$x\n";

执行时会打印 12。

更新 2:感谢 Eric Strom 在这个新版本下面的评论,使其更加清晰:

use strict;
use warnings;

my $x = 12;
my $y;

BEGIN {
    $x = 14;
    print "x => $x\n";
    $y = 16;
    print "y => $y\n";
}

print "x => $x\n";
print "y => $y\n";

输出是

x => 14
y => 16
x => 12
y => 16

再次感谢埃里克!

最佳答案

虽然可以按照您的描述使用 BEGINEND block ,但典型用法是进行影响后续编译的更改。

例如,use Module qw/a b c/;语句实际上意味着:

BEGIN {
   require Module;
   Module->import(qw/a b c/);
}

类似地,子例程声明sub name {...}实际上是:

BEGIN {
   *name = sub {...};
}

由于这些 block 在编译时运行,因此 block 运行后编译的所有行都将使用 BEGIN block 所做的新定义。这就是您如何在没有括号的情况下调用子例程,或者各种模块如何“改变世界的工作方式”。

END block 可用于清除 BEGIN block 所做的更改,但更常见的是使用带有 DESTROY 的对象方法。

如果您尝试清理的状态是 DBI 连接,则可以在 END block 中执行此操作。但出于多种原因,我不会在 BEGIN block 中创建连接。通常不需要在编译时使连接可用。在编译时执行连接到数据库之类的操作会大大减慢您使用的任何具有语法检查功能的编辑器(因为它运行 perl -c)。

关于perl - Perl 中 BEGIN block 的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3998619/

相关文章:

perl - 将 Perl 数组扩展为 shell 命令参数

perl - Perl v5.18的排序可以理解词法子例程吗?

perl - 如何更新散列属性,更新 Perl Moose 中的其他散列属性

perl - 在 Perl 中创建链表结构

arrays - 将数组变成字符串

regex - 使用捕获组匹配重复仅返回最终匹配值

perl - 如何写出或读入 Perl 散列的数组?

Linux/PERL : split a single line into multiple lines

regex - Perl正则表达式匹配特殊字符

arrays - 处理输入数据时获取 "The second parameter of split is a string, not an array"