从DBI插入的Perl模块“不能调用方法'prepare'".错误 [英] Perl module, inhereting from DBI , "Can't call method 'prepare'" error

查看:446
本文介绍了从DBI插入的Perl模块“不能调用方法'prepare'".错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
Perl + POO和无法调用方法准备"

我学习了poo,我开始使用perl,创建了这个模块,但是当我调用segudno方法时,我跳过了以下错误在串联(.)中使用未初始化的值$ database ... ...后跟'Can'不能将方法称为准备",我真的不明白,有什么建议吗?

#!/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;

在另一个文件中,用于调用msg并创建了对象.

#!/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子.但是,此子项需要几个您不提供的参数,包括一个受祝福的对象.您可能要修复该问题.参数中还应包含$database$hostname.

您对conexion的调用将总是 被执行,因为my $var创建一个新变量并用undef对其进行初始化-undef的取反是真实值. /p>

然后您有以下声明:

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中重新定义它.但是,它不是相同的变量,因为这些变量位于不同的范围内.

相反,您可能会在要传递的对象中添加字段mysqlopenconnect,因为这是对象数据.然后,您可以像hostdatabase字段一样使用此信息.

此外,不要在没有对象的情况下调用方法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;
}

Possible Duplicate:
Perl + POO and “Can't call method ”prepare"

I learned poo and i got to play with perl, create this module but when I call the segudno method I skip the following error 'Use of uninitialized value $database in concatenation ( .) ... ' Followed by 'Can't call method 'prepare' mm i don't really understand, any suggestions?

#!/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;

in other file for call msg and created objected.

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

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

this output in console.

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.

any idea?

thanks.

解决方案

Your code includes this line:

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

You call your conexion sub with no arguments. However, this sub expects several arguments, including a blessed object, that you don't provide. You might want to fix that. $database and $hostname also are expected in the arguments.

Your call to conexion will always be executed, because my $var creates a new variable and initializes it with undef—and the negation of undef is a true value.

Then you have this statement:

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

my creates a new variable $connect on which you try to call the method prepare. This doesn't work, as the created variable is no blessed reference but simply undef.

Scope in Perl

Here is a verbose example on how lexical scope with my works in 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

You define a my variable mysqlopen in conexion, then redefine it in consulta. It is, however, not the same variable, as these variables reside in different scope.

Instead, you are likely to add fields mysqlopen and connect in the object you are passing around, as this is object data. You can then use this information just like the host or database fields.

Also, do not call the method conexion without an object. Objects are usually created with new.


Edit

It is quite difficult for me to debug your code and parse your English at the same time, so here is your code with the worst bugs removed. However, I have no experience with DBI, so it may not work directly:

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

这篇关于从DBI插入的Perl模块“不能调用方法'prepare'".错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆