将perl变量导入模块

时间:2014-02-22 10:23:14

标签: perl variables perl-module

perl有没有办法将变量从主脚本导入模块?

这是我的main.pl:

#!/usr/bin/perl -w
use DBI;
our $db = DBI->connect(...);

__END__

现在我想在我的模块中使用$ db变量,因为我想避免重复连接和重复代码......这可能吗?

2 个答案:

答案 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或者将处理数据库连接池/抽象。