【问题标题】:Perl module, inhereting from DBI , "Can't call method 'prepare'" error [duplicate]Perl 模块,从 DBI 继承,“无法调用方法 'prepare'”错误 [重复]
【发布时间】:2012-09-21 07:04:49
【问题描述】:

可能重复:
Perl + POO and “Can't call method ”prepare"

我学会了 poo,我开始玩 perl,创建了这个模块,但是当我调用 segudno 方法时,我跳过了以下错误“在连接中使用未初始化的值 $database (.) ...”,然后是“可以” 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;

在其他文件中调用消息并创建对象。

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

有什么想法吗?

谢谢。

【问题讨论】:

  • como es la programacion orientada a objecto!! no hice referencia a implementarla en perl、sino la estructura de objectos、attributors、metodos 等!好吗?
  • 主题相似,不同的主题,除了我想删除它以使其不'重复',但他不会让我!

标签: perl perl-module dbi


【解决方案1】:

您的代码包括这一行:

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

你打电话给你的conexion 没有参数。然而,这个 sub 需要几个参数,包括你不提供的祝福对象。你可能想解决这个问题。 $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 中重新定义它。但是,它不是同一个变量,因为这些变量位于不同的范围内。

相反,您可能会在传递的对象中添加字段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;
}

【讨论】:

  • 我明白了!但不是如何修改它,如果删除 if (!my $mysqlopen) { &conexion(); }, 我的 $mysqlopen =1;返回并输出此错误 Can't call method "prepare" on an undefined value at MysqlTest.pm 第 30 行。
  • @opmeitle 我添加了一些关于您遇到的范围界定问题的信息。
  • 已经改代码,删掉不需要但不太明白的bless $connect用法,然后在咨询和他的ves中使用$connect->prepare,
  • @opmeitle 对不起,我不太明白你刚才说的话,所以我只是修复了你代码中的错误(并以我自己的风格编写)并将关键部分转储到我的回答。
  • 是的,我完全理解,代码写得不好,谢谢!为了您的时间和解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
相关资源
最近更新 更多