Perl模块,源自DBI;Can';t调用方法&x27;准备'&引用;错误

Perl模块,源自DBI;Can';t调用方法&x27;准备'&引用;错误,perl,perl-module,dbi,Perl,Perl Module,Dbi,可能重复: 我学习了poo,并且开始使用perl,创建这个模块,但是当我调用segudno方法时,我跳过了下面的错误“在连接中使用未初始化的值$database(.)…”然后是“不能调用方法”准备“嗯,我真的不明白,有什么建议吗 #!/usr/bin/perl use warnings; use strict; use DBI; use DBD::mysql; package MysqlTest; sub new{ my $class = shift; my $query

可能重复:

我学习了poo,并且开始使用perl,创建这个模块,但是当我调用segudno方法时,我跳过了下面的错误“在连接中使用未初始化的值$database(.)…”然后是“不能调用方法”准备“嗯,我真的不明白,有什么建议吗

#!/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;
在调用消息和创建对象的其他文件中

#!/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.
有什么想法吗


谢谢。

您的代码包括这一行:

if (!my $mysqlopen) { &conexion(); }
您可以不带任何参数调用
conexion
sub。但是,该子类需要几个参数,包括您没有提供的受祝福对象。你可能想解决这个问题<参数中还应包含code>$database和
$hostname

您对
conexion
的调用将始终被执行,因为
my$var
创建了一个新变量,并使用
undef
对其进行初始化,
undef
的否定值为真值

那么你有这样的说法:

our $result = my $connect->prepare($id);
my
创建一个新变量
$connect
,您可以尝试在该变量上调用方法
prepare
。这不起作用,因为创建的变量不是受祝福的引用,只是
undef

Perl中的作用域 下面是一个详细的示例,介绍了
my
的词法作用域如何在Perl中工作

# $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
conexion
中定义
my
变量
mysqlopen
,然后在
consulta
中重新定义它。但是,它不是同一个变量,因为这些变量位于不同的范围内

相反,您可能会在正在传递的对象中添加字段
mysqlopen
connect
,因为这是对象数据。然后,您可以像
主机
数据库
字段一样使用此信息

另外,不要在没有对象的情况下调用方法
conexion
。对象通常是使用
new
创建的


编辑 我很难同时调试你的代码和解析你的英语,所以这里是你的代码,去掉了最坏的bug。但是,我没有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;
}

我理解!但不是如何修改它,如果删除(!my$mysqlopen){&conexion();},my$mysqlopen=1;返回并输出此错误无法在MysqlTest.pm第30行对未定义的值调用方法“prepare”。@opmeitle我添加了一些关于您存在的作用域问题的信息。请更改代码,删除您不需要但不太了解bless$connect的用法的内容,然后在$connect->prepare中咨询并使用它,@对不起,我不太明白你刚才说的话,所以我只是修复了你代码中的错误(并以我自己的风格编写),并在我的答案中删除了关键部分。是的,我完全理解,代码写得很糟糕,谢谢!谢谢你的时间和解释。这是东方的一个目标!!无需参考perl实现、对象结构、atributos、metodos等!好吗?主题类似于不同主题的演讲,除了我想删除它,这样它就不会“重复”,但他不会让我!