我收到此错误
如果没有包或对象引用,则无法调用方法“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();
othermodule1:
my $databaseHandler = unset;
sub connectToDatabase
{
$databaseHandler = DBI->connect('DBI:mysql:db','db','pwd') or die "Could not connect to database: ";
}
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;
}
答案 0 :(得分: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
)不显示/重要,因为第一个模块的{{1}声明将该变量放在文件其余部分的范围内(包括主脚本)。但如果你的模块在自己的文件中,它将停止工作(下面的第二个例子)
my $databaseHandler
答案 1 :(得分:2)
您正在混合词汇范围和全球范围。 my
将变量声明为词法 - 它不能在其定义范围之外看到。没有它,它是(包)全局的,但是如果你use strict
,你会收到关于它的警告。
所以在该模块之外看不到othermodule1中的my $databaseHandler
。该值可以从函数返回,但该变量名称对模块是私有的。