-2

重複の可能性:
Perl + POO および「メソッドを呼び出すことができません」prepare"

私はうんちを学び、私はperlで遊んで、このモジュールを作成しましたが、segudnoメソッドを呼び出すと、次のエラーをスキップします 'Use of uninitialized value $database in concatenation ( .) ...' 続いて 'Can't call method 'prepare' mm よくわかりません。何か提案はありますか?

#!/usr/bin/perl

use warnings;
use strict;
use DBI;
use DBD::mysql;

package MysqlTest;

sub new{
    my $class = shift;
    my $query={};
    bless($query, $class);
}
sub conexion{
    my $self=shift;
    my($database, $hostname, $user, $pwd)=@_;
    $self->{"host"}=$hostname;
    $self->{"database"}=$database;
    $self->{"user"}=$user;
    $self->{"pass"}=$pwd;
    our $connect = DBI->connect("DBI:mysql:database=$database;host=$hostname;", $user, $pwd) or die $DBI::errstr;
    my $mysqlopen = 1;
return;
}
sub consulta{
    my $self=shift;
    if (!my $mysqlopen) { &conexion(); }
    my $id = "SELECT * FROM save_bookmarks WHERE id='123'";
    our $result = my $connect->prepare($id);
    $result->execute();
    my @resultado = $result->fetchrow_array();
    print "@resultado\n";
    return;
}
sub datos{
    my $self=shift;
    print "::DATOS DE ACCESO::\n";
    while ((my $key, my $value)=each(%$self)){
        print "$key => $value\n";
    }
}
1;

call msg 用の他のファイルに作成され、objected が作成されました。

#!/usr/bin/perl
use MysqlTest;
use warnings;
use strict;

my $mysqltest = MysqlTest->new();
$mysqltest->conexion("bookmarks", "localhost", "root", "pass");
$mysqltest->consulta();

この出力はコンソールに表示されます。

Use of uninitialized value $database in concatenation (.) or string at MysqlTest.pm line 23.
Use of uninitialized value $hostname in concatenation (.) or string at MysqlTest.pm line 23.
Can't call method "prepare" on an undefined value at MysqlTest.pm line 31.

何か案が?

ありがとう。

4

1 に答える 1

4

コードには次の行が含まれています。

if (!my $mysqlopen) { &conexion(); }

conexion引数なしでサブルーチンを呼び出します。ただし、このサブルーチンは、提供されていない、祝福されたオブジェクトを含むいくつかの引数を想定しています。あなたはそれを修正したいかもしれません。$databaseまた$hostname、引数で期待されます。

への呼び出しconexion常に実行されます。これmy $varは、新しい変数を作成し、それを初期化するためですundef—そして、の否定undefは真の値です。

次に、次のステートメントがあります。

our $result = my $connect->prepare($id);

my$connectメソッドを呼び出そうとする新しい変数を作成しますprepare。作成された変数は祝福された参照ではなく、単にundef.

Perl のスコープ

myPerlでレキシカル スコープがどのように機能するかについての詳細な例を次に示します。

# $var doesn't exist

sub foo {
   # $var doesn't exist
   my $var;
   # $var exists
   bar();
   # $var exists
}

# $var doesn't exist

sub bar {
   # $var doesn't exist
   return;
}

# $var doesn't exist

myで変数mysqlopenを定義conexionし、 で再定義しconsultaます。ただし、これらの変数は異なるスコープに存在するため、同じ変数ではありません。

代わりに、これはオブジェクト データであるため、渡すオブジェクトにフィールドmysqlopenとオブジェクトを追加する可能性があります。connectこの情報は、hostまたはdatabaseフィールドと同じように使用できます。

conexionまた、オブジェクトなしでメソッドを呼び出さないでください。通常、オブジェクトは で作成されnewます。


編集

コードのデバッグと英語の解析を同時に行うのは非常に難しいため、最悪のバグを取り除いたコードを次に示します。ただし、DBI の経験がないため、直接動作しない可能性があります。

sub conexion{
   my $self=shift;
   die "I need args!" unless @_;
   my($database, $hostname, $user, $pwd)=@_;
   $self->{host}     = $hostname;
   $self->{database} = $database;
   $self->{user}     = $user;
   $self->{pass}     = $pwd;
   $self->{connect}  = DBI->connect(
      "DBI:mysql:database=$database;host=$hostname;",
       $user,
       $pwd,
   ) or die $DBI::errstr;
   $self->{mysqlopen}= 1;
   return;
}

sub consulta{
   my $self = shift;
   if (not $self->{mysqlopen}) {
      die "This object wants to be conexioned before you consulta anything";
      # you could also do
      #    $self->conexion(DEFAULT_VALUES);
      # but then you would really *have* to provide defaults!
   }
   my $id = "SELECT * FROM save_bookmarks WHERE id='123'";
   my $result = $self->{connect}->prepare($id);
   $result->execute();
   my @resultado = $result->fetchrow_array();
   print "@resultado\n";
   return;
}
于 2012-09-29T20:39:12.597 に答える