BEGIN块在Perl中的作用是什么?

前端之家收集整理的这篇文章主要介绍了BEGIN块在Perl中的作用是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我知道BEGIN块是在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块允许程序员在执行主程序之前确保任何所需的资源可用。

所以我一直在使用BEGIN块,以确保像DB连接的事情已经建立,并可供主程序使用。类似地,我使用END块来确保所有资源在程序终止之前被关闭删除,终止等。

今天上午的讨论,我想知道这是错误的方式来看看BEGIN和END块。

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

更新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

再次感谢埃里克!

解决方法

你试过换出一个INIT {}块的BEGIN {}块吗?这是像modperl这样使用“编译一次,运行多”模型的标准方法,因为您需要在每次单独运行时重新初始化一次,而不是在编译期间一次。

但我必须问,为什么它都在特殊的块。为什么不只是做一些prepare_db_connection()函数,然后在程序启动时根据需要调用它?

如果一个模块文件中的主线代码被使用,那么在BEGIN {}中不起作用的东西也会有同样的问题。这是使用INIT {}块的另一个可能的原因。

我也看到致命的相互递归的问题,必须解开使用类似require而不是使用,或INIT {}而不是BEGIN {}。但这是非常罕见的。

考虑这个程序:

% cat sto-INIT-eg
#!/usr/bin/perl -l
print               "    PRINT: main running";
die                 "    DIE:   main dying\n";
die                 "DIE XXX /* NOTREACHED */";
END         { print "1st END:   done running"    }
CHECK       { print "1st CHECK: done compiling"  }
INIT        { print "1st INIT:  started running" }
END         { print "2nd END:   done running"    }
BEGIN       { print "1st BEGIN: still compiling" }
INIT        { print "2nd INIT:  started running" }
BEGIN       { print "2nd BEGIN: still compiling" }
CHECK       { print "2nd CHECK: done compiling"  }
END         { print "3rd END:   done running"    }

当仅编译时,它产生:

% perl -c sto-INIT-eg 
1st BEGIN: still compiling
2nd BEGIN: still compiling
2nd CHECK: done compiling
1st CHECK: done compiling
sto-INIT-eg Syntax OK

当编译和执行时,它产生:

% perl sto-INIT-eg 
1st BEGIN: still compiling
2nd BEGIN: still compiling
2nd CHECK: done compiling
1st CHECK: done compiling
1st INIT:  started running
2nd INIT:  started running
    PRINT: main running
    DIE:   main dying
3rd END:   done running
2nd END:   done running
1st END:   done running

而shell报告退出255,每个模具。

你应该能够安排连接发生在你需要的时候,即使BEGIN {}证明太早了。

嗯,只是记得。没有机会你在BEGIN {}中使用DATA做什么,是吗?这直到翻译运行才设置;它不对编译器开放。

猜你在找的Perl相关文章