1

我收到这个错误

不能在没有包或对象引用的情况下调用方法“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();

其他模块1:

my $databaseHandler = unset;

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

其他模块2:

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;
}
4

2 回答 2

6
  $dbhandler = @_;

是问题。您在标量上下文中进行分配 - 因此 的值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

第二个不相关的问题是您错误地命名了变量。你$dbh在主脚本中分配它之后你继续使用它$databaseHandler

if ( defined $databaseHandler )  # BAD
if ( defined $dbh )              # GOOD

如果您的模块与上面的主脚本在同一个文件中定义,则上述错误(使用$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
于 2011-09-14T16:37:17.860 回答
2

您正在混合词法范围和全局范围。 my将变量声明为词法 - 在其定义范围之外无法看到它。没有它,它是(包)全局的,但是如果你use strict.

因此my $databaseHandler在该模块之外无法看到 othermodule1 内部。该值可以从函数返回,但该变量名是模块私有的。

于 2011-09-14T16:35:45.083 回答