perl
有没有办法将变量从主脚本导入模块?
这是我的main.pl:
#!/usr/bin/perl -w
use DBI;
our $db = DBI->connect(...);
__END__
现在我想在我的模块中使用$ db变量,因为我想避免重复连接和重复代码......这可能吗?
答案 0 :(得分:5)
您可以参考其他软件包中的$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__
答案 1 :(得分:0)
您始终可以将db句柄传递给方法。我不是这种方法的粉丝,但我们有使用这种方法运行的代码。
问题恕我直言正在调试中。这使得很难从模块中的代码中了解有关db句柄本身的任何信息,尽管这对您来说可能不是问题。想象一下,无论如何调试使用db句柄的代码,但你不知道它来自哪里。如果从类中的方法获取数据库句柄,则可以将其跟踪到该子例程,并立即获得一些信息。这绝对是我首选的做事方式。
如果你确实传入了DB句柄,你应该进行一些输入验证,例如检查$ dbh-> isa('DBI :: db')(我认为这是db处理的祝福的类)
然而,我的偏好是在你的类中有一个子程序来获取db句柄,或者根据你传入的信息,或者通过sub本身的信息。需要考虑的一件事是,如果您使用DBI,connect_cached()方法非常有用。来自DBI文档:
connect_cached类似于“connect”,除了返回的数据库句柄也存储在与给定参数关联的哈希中。如果使用相同的参数值对connect_cached进行另一次调用,则如果它仍然有效,则将返回相应的缓存$ dbh。如果已断开连接或ping方法失败,则缓存的数据库句柄将替换为新连接。
使用某种类型的db句柄缓存,无论您是在脚本中还是在类中创建了db句柄,都会为您提供相同的连接。
因此,我建议在类中创建一个方法,该方法将获取复制db句柄创建所需的所有参数,就像在脚本中一样,并考虑使用connect_cached,Apache2 :: DBI或者将处理数据库连接池/抽象。