1

このエラーが発生します

... [私の $execute で始まる createSqlTable 行内] で、パッケージまたはオブジェクト参照なしでメソッド「prepare」を呼び出すことはできません。

次のようなコード (スニペット):

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

2 番目の無関係な問題は、変数の名前を間違えたことです。$dbhメイン スクリプトを割り当てた後も、代わりに使用し続けます$databaseHandler

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

上記の間違い ( の$databaseHandler代わりに使用$dbh) は、モジュールがその上のメイン スクリプトと同じファイルで定義されている場合、表示されませんmy $databaseHandler。 . ただし、モジュールが独自のファイルにある場合は動作しなくなります (以下の 2 番目の例)

$ 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 $databaseHandlerothermodule1 の内部は、そのモジュールの外部には表示されません。値は関数から返すことができますが、その変数名はモジュールに対してプライベートです。

于 2011-09-14T16:35:45.083 に答える