在哪里放置初始化代码(连接到数据库、生成内容、加载数据文件等)?
以下是一些现有的选项:
BEGIN{} d时执行use中的代码。(+)良好的封装。
(-)所有东西都与数据库、配置、特定文件位置等相关联。很难隔离单元测试,更难运行代码片段来查找bug,就像在perl -MFoo -d -we 'Foo->new'中那样
startup.pl等)(-)代码远离使用的地方,很容易忘记一些东西。
(-)初始化全部或无。
startup() (或其他名称)例程。(-)仍然很容易忘记运行它。
下面是问题所在(当然,Apache也是这样):
bash$ plackup -e 'use warnings; INIT{ warn "foo"; }; sub { warn "here"; return [200, [], []] };'
Too late to run INIT block at (eval 7) line 1.
HTTP::Server::PSGI: Accepting connections at http://0:5000/
here at (eval 7) line 1.
127.0.0.1 - - [20/Nov/2014:14:18:08 +0200] "GET / HTTP/1.1" 200 - "-" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:33.0) Gecko/20100101 Firefox/33.0"注意Too late to call INIT警告,输出中没有"foo“的迹象。
现在,我希望有一个模块,其用途如下:
在项目模块中:
use Init::Queue sub {
get_dbh();
load_file();
build_cache();
}; # postpone till explicitly called在生产/初始化代码中:
Init::Queue->startup();
# this executes all startup blocks,
# in order of appearance有这样一个模块吗?如果没有,是否需要?还是我忽略了一种更简单的方法?
发布于 2014-11-20 14:41:29
答案是“视情况而定”。但就我个人而言,我倾向于采取‘第一次使用’的方法。当您进行面向对象的操作时,这是相对容易的--将构造函数挂钩并将其设置起来。
对于非OO,我实际上倾向于这样做:
{
my $thing_to_init;
sub init {
$thing_to_init = 1;
}
sub call_some_function {
init() unless defined $thing_to_init;
#do everything else
}
}因为它在闭包中,所以不能从模块命名空间访问$thing_to_init,但是您可以手动调用init()子,或者在它启动时让它进入它自己。
https://stackoverflow.com/questions/27039815
复制相似问题