Perl module, inhereting from DBI , “Can't call method 'prepare'” error [duplicate]

主宰稳场 提交于 2019-12-13 09:33:38

问题


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.


回答1:


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


来源:https://stackoverflow.com/questions/12656212/perl-module-inhereting-from-dbi-cant-call-method-prepare-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!