OVH Cloud OVH Cloud

Class::Singleton et DESTROY

1 réponse
Avatar
Alexandre Vaissière (Starch)
Bonjour,

Je viens de lire le _Practical mod_perl_, et j'y ai trouvé le bout de
code suivant, qui m'intéresse assez. Le but étant de faire un Singleton
d'un handler sur une base de données.

##############################################
1 package Book::DBIHandle;
2
3 use strict;
4 use warnings;
5
6 use DBI;
7
8 use Class::Singleton;
9 @Book::DBIHandle::ISA = qw(Class::Singleton);
10
11 sub _new_instance {
12 my($class, $args) = @_;
13
14 my $self = DBI->connect($args->{dsn}, $args->{user},
15 $args->{passwd}, $args->{options})
16 or die "Cannot connect to database: $DBI::errstr";
17
18 return bless $self, $class;
19 }
20
21 sub dbh {
22 my $self = shift;
23 return $$self;
24 }
25 1;
##############################################

Déjà je pense qu'il y a une typo à la ligne 14, que ce devrait être my
$self = \DBI->... (et effectivement, sans, ça ne marche pas).

Mon problème est que je voudrais mettre dans le destructeur un appel à
disconnect pour se déconnecter de la base de données, je rajoute donc le
code suivant :

##############################################
24 }
25
26 sub DESTROY {
27 my $self = shift;
28 $$self->disconnect;
29 }
30 1;
##############################################

Le problème est qu'avec cette méthode, je me fais envoyer bouler à la
fin de mon script avec un gentil :

(in cleanup) Can't call method "disconnect" on an undefined value at
Book/DBIHandle.pm line 28 during global destruction.

Et je ne comprends pas pourquoi il fait ça, donc si quelqu'un pouvait
m'expliquer ce comportement, il n'y a que si j'utilise Class::Singleton
que ce problème se produit.

Merci par avance.
Starch'

1 réponse

Avatar
Emmanuel Florac
Le Sat, 15 Oct 2005 10:26:00 +0200, Alexandre Vaissière a écrit :


Et je ne comprends pas pourquoi il fait ça, donc si quelqu'un pouvait
m'expliquer ce comportement, il n'y a que si j'utilise Class::Singleton
que ce problème se produit.


Pour faire un singleton, il suffit de faire une variable de package. Part
exemple, tu peux faire un package qui hérite de DBI, tu rajoutes juste
ça :

package DBIsingleton;

use base DBI;

# variable de package
my $instance ;

sub connect {
my $proto = shift;
my $params = shift;
# le singleton est déjà défini?
unless ( $instance ) {
$instance = SUPER::connect( # paramètres ...
)
}

return $instance
}

Personnellement ça me parait beaucoup plus simple... En particulier le
fait que tu sois obligé d'utiliser une référence à DBI dans ton
exemple c'est pas sain à mon avis, tu devrais pouvoir l'utiliser
normalement.


--
Quis, quid, ubi, quibus auxiliis, cur, quomodo, quando