【问题标题】:Import perl variables into the module将 perl 变量导入模块
【发布时间】:2014-02-24 04:49:06
【问题描述】:
perl 有没有办法将变量从主脚本导入到模块中?
这是我的 main.pl:
#!/usr/bin/perl -w
use DBI;
our $db = DBI->connect(...);
__END__
现在我想在我的模块中使用 $db 变量,因为我想避免重复连接和重复代码...有可能吗?
【问题讨论】:
标签:
perl
variables
perl-module
【解决方案1】:
您可以通过在其他包中引用$main::db 来做到这一点。如果没有其他给定,main 命名空间总是指向主命名空间中的全局变量。你应该阅读package。
请注意,这不是一个好主意,因为您的模块将依赖于 main 的连接。相反,您应该以允许您传入数据库句柄的方式构造对象。如果您不惜一切代价需要数据库连接,请让它们抛出异常或创建自己的数据库句柄。
如果您不使用 OO 代码,请让数据库处理每个函数调用的参数。
另请注意,最好将数据库句柄命名为 $dbh。
让我们看看非 OO (Foo) 和 OO (Bar) 的情况。
# this is package main (but you don't need to say so)
use strictures;
use DBI;
use Foo;
use Bar;
my $dbh = DBI->connect($dsn);
Foo::frobnicate($dbh, 1, 2)
my $bar = Bar->new(dbh => $dbh);
$bar->frobnicate(23);
package Foo;
use strictures;
sub frobnicate {
my ($dbh, $one, $two) = @_;
die q{No dbh given} unless $dbh; # could check ref($dbh)
$dbh->do( ... );
return;
}
package Bar;
use strictures;
sub new {
my ($class, %args) = @_;
die q{No dbh given} unless $args{dbh};
return bless \%args, $class;
}
sub frobnicate {
my ($self, $stuff) = @_;
$self->{dbh}->do(q{INSERT INTO bar SET baz=?}, undef, $stuff);
return;
}
__END__
【解决方案2】:
您始终可以将数据库句柄传递给方法。我不喜欢这种方法,但我们有使用这种方法的代码。
恕我直言,问题在于调试。很难从模块中的代码中了解有关 db 句柄本身的任何信息,尽管这对您来说可能不是问题。想象一下,但是要调试使用 db 句柄的代码,但您不知道它来自哪里。如果您从类中的方法获取数据库句柄,则可以将其跟踪到该子例程,并立即获得一些信息。这绝对是我喜欢的做事方式。
如果你确实传入了一个 DB 句柄,你应该做一些输入验证,例如检查 $dbh->isa('DBI::db') (我认为这是 db 句柄被祝福的类)。
然而,我的偏好是在你的类中有一个子例程来获取数据库句柄,或者基于你传入的信息,或者通过子本身中的信息。要考虑的一件事是,如果您使用 DBI,connect_cached() 方法非常有用。来自 DBI 文档:
connect_cached 类似于“connect”,只是返回的数据库句柄也存储在与给定参数关联的哈希中。如果使用相同的参数值再次调用 connect_cached,则如果它仍然有效,则将返回相应的缓存 $dbh。如果已断开连接或 ping 方法失败,则缓存的数据库句柄将替换为新连接。
使用某种类型的数据库句柄缓存,无论您是在脚本中还是在类中创建数据库句柄,都会为您提供相同的连接。
因此,我建议在您的类中创建一个方法,该方法采用复制创建数据库句柄所需的所有参数,就像您在脚本中所做的那样,并考虑使用 connect_cached、Apache2::DBI 或其他将处理数据库连接池/抽象。