在Perl中,如果在函数之间传递(通过return或input param),则从DBI-> connect返回的对象/句柄超出范围?

the*_*now 1 perl scope function dbi prepare

我收到这个错误

如果没有包或对象引用,则无法调用方法"prepare"... [在以$ execute开头的createSqlTable行中].

代码类似于以下(代码片段):

use othermodule1;
use othermodule2;

my $dbh = othermodule1::connectToDatabase();

if ( defined $databaseHandler )
{
  print "\ndatabaseHandler is defined here after calling connectToDatabase\n";
}

othermodule2::setDatabaseHandler( $databaseHandler );

othermodule2::createSqlTable();
Run Code Online (Sandbox Code Playgroud)

othermodule1:

my $databaseHandler = unset;

sub connectToDatabase
{
  $databaseHandler = DBI->connect('DBI:mysql:db','db','pwd') or die "Could not    connect to database: ";
}
Run Code Online (Sandbox Code Playgroud)

othermodule2:

my $dbhandler = unset;

sub setDatabaseHandler
{
  $dbhandler = @_;
}


sub createSqlTable()
{
  my $query = "CREATE TABLE atable ( a CHAR(30) NULL, b CHAR(30) NULL )"; # etc...

  my $execute = $dbhandler ->prepare($myquery) or die "Couldn't prepare statement: " . $dbhandler->errstr;
  $execute->execute or die "Couldn't execute statement: " . $dbhandler->errstr;
}
Run Code Online (Sandbox Code Playgroud)

DVK*_*DVK 6

  $dbhandler = @_;
Run Code Online (Sandbox Code Playgroud)

是问题.您正在分配在标量环境-这样的价值scalar(@_)将被分配到$dbhandler-在这种情况下,1,因为你通过了1元的参数列表.

它应该是:($dbhandler) = @_;使用列表上下文或作为替代惯用法, $dbhandler = shift;

对比:

$ perl -e 'sub x { $x = @_ ; print "$x\n"} ; x(33);'
1
$ perl -e 'sub x { ($x) = @_ ; print "$x\n"} ; x(33);'
33
Run Code Online (Sandbox Code Playgroud)

第二个无关的问题是你错误地命名了你的变量.$dbh在分配之后你还有主脚本,你继续使用$databaseHandler.

if ( defined $databaseHandler )  # BAD
if ( defined $dbh )              # GOOD
Run Code Online (Sandbox Code Playgroud)

如果您的模块在与其上方的主脚本相同的文件中定义,则上述错误(使用$databaseHandler而不是$dbh)不显示/重要,因为第一个模块的my $databaseHandler声明将该变量放在文件其余部分的范围内(包括主脚本) .但如果你的模块在自己的文件中,它将停止工作(下面的第二个例子)

$ cat /tmp/p1.pm
package p1;
my $v = undef;
sub x {
    $v = 3;
}
1;
$ cat /tmp/x1.pl
use p1;
my $c = p1::x();
my $v_print =  defined $v ? $v : "_UNDEF_";
print "v=$v_print\nc=$c\n";

$ perl -I /tmp /tmp/x1.pl
v=_UNDEF_
c=3

###############################################

$ cat /tmp/x2.pl
package p1;
my $v = undef;
sub x {
    $v = 3;
}
1; # END package p1
package main;
my $c = p1::x();
my $v_print =  defined $v ? $v : "_UNDEF_";
print "v=$v_print\nc=$c\n";

$ perl /tmp/x2.pl
v=3
c=3
Run Code Online (Sandbox Code Playgroud)