Plusieurs implementations d'une interface pour un module

Le
Olivier Croquette
Salut à tous

J'en suis encore à mes débuts en Perl, et j'ai le problème suivant: je
veux écrire sous forme de modules plusieurs implémentations d'une même
interface.
Le but est de décider à la compilation (par exemple en fonction d'une
variable d'environnement) de quelle implémentation utiliser.

Bref, j'ai:

main.pl
module.pm
module_imp1.pm
module_imp2.pm

main est censé faire un "use module", qui "redirigerait" vers
l'implémentation correcte.
Bien sûr, je veux éviter d'avoir à écrire quoique soit dans module.pm
(surtout pas une fonction par fonction à transférer).

J'ai essayé de faire ça à base de ISA et Exporter, mais je ne suis
arrivé à rien, et je ne suis pas sûr d'être sur la bonne piste.

Des idées peut-être?

Merci!
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
jl_morel
Le #1157589
Dans l'article a dit...

J'en suis encore à mes débuts en Perl, et j'ai le problème suivant: je
veux écrire sous forme de modules plusieurs implémentations d'une même
interface.
Le but est de décider à la compilation (par exemple en fonction d'une
variable d'environnement) de quelle implémentation utiliser.

Bref, j'ai:

main.pl
module.pm
module_imp1.pm
module_imp2.pm

main est censé faire un "use module", qui "redirigerait" vers
l'implémentation correcte.
Bien sûr, je veux éviter d'avoir à écrire quoique soit dans module.pm
(surtout pas une fonction par fonction à transférer).

J'ai essayé de faire ça à base de ISA et Exporter, mais je ne suis
arrivé à rien, et je ne suis pas sûr d'être sur la bonne piste.

Des idées peut-être?



Peut être mettre dans module.pm (si j'ai bien compris la question)

if ( CONDITION ) {
require module_imp1;
}
else {
require module_imp2;
}

Si vous avez beaucoup d'implémentations, vous pouvez même utiliser la forme
require $implémentation;
où $implémentation est obtenu par une liste, un hash...etc

Si vous avez des constantes à importer il faut les gérer vous même en
appelant la fonction import() de chaque module.

HTH

--
J-L.M.
http://www.bribes.org/perl

ocroquette
Le #1157588
On Feb 28, 11:38 pm, (Jean-Louis MOREL) wrote:
Peut être mettre dans module.pm (si j'ai bien compris la question)

if ( CONDITION ) {
require module_imp1;}
else {
require module_imp2;
}


OK, mais le problème est de faire en sorte que:
use module;
f();
appelle la fonction correspondante de l'implementation, et ce
automatiquement, avec le moins de code possible.

J'ai trouve une solution a base de ISA:

package module_imp1;

sub foo {
print("Inside module_imp1::foon");
}

package module;
@ISA = (module_imp1);

package main;
module->foo();


C'est exactement ce que je veux faire, néanmoins cela oblige à
utiliser une syntaxe "objet" (->) alors que je travaille sur un
programme complètement orienté fonctions. :(

ocroquette
Le #1158153
On Feb 29, 10:34 am, wrote:
C'est exactement ce que je veux faire, néanmoins cela oblige à
utiliser une syntaxe "objet" (->) alors que je travaille sur un
programme complètement orienté fonctions. :(


Une autre solution, basée sur AUTOLOAD et la recherche dynamique de
fonction cette fois:

package module_imp1;
use strict;

sub foo {
print("Inside module_imp1::foon");
}


package module;

sub AUTOLOAD {
our $AUTOLOAD;
no strict "refs";
my $fnname = (split(/::/,$AUTOLOAD))[-1];
my $fn = "module_imp1::" . $fnname;
if ( exists &$fn ) {
return &$fn(@_);
}
die("Error: Unknown function $AUTOLOAD @_n");
}


package main;
module::foo();


Ca correspond mieux à mon cahier des charges, mais c'est pas très
élegant :-/

Paul Gaborit
Le #1158152
À (at) Fri, 29 Feb 2008 01:34:04 -0800 (PST),
écrivait (wrote):
OK, mais le problème est de faire en sorte que:
use module;
f();
appelle la fonction correspondante de l'implementation, et ce
automatiquement, avec le moins de code possible.


C'est un problème d'import/export de fonctions(). Il suffit que chaque
implémentation exporte correctement les fonctions voulues (via
Exporter).

Ensuite le package 'Module' peut faire :

----------------------------------------
package Module;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK;
our @EXPORT;

BEGIN {
my $implementation;
if (defined $ENV{IMPLEMENTATION1}) {
$implementation = 'Module::Imp1';
} else {
$implementation = 'Module::Imp2';
}
warn "Choix : $implementationn";

eval "use $implementation";
@EXPORT = @{"${implementation}::EXPORT"};
@EXPORT_OK = @{"${implementation}::EXPORT_OK"};
}

1;
----------------------------------------


--
Paul Gaborit - Perl en français -
jl_morel
Le #1162573
Dans l'article <c0b69661-59f6-4d3c-8884-
, a dit...

On Feb 28, 11:38 pm, (Jean-Louis MOREL) wrote:
Peut être mettre dans module.pm (si j'ai bien compris la question)

if ( CONDITION ) {
require module_imp1;}
else {
require module_imp2;
}


OK, mais le problème est de faire en sorte que:
use module;
f();
appelle la fonction correspondante de l'implementation, et ce
automatiquement, avec le moins de code possible.

J'ai trouve une solution a base de ISA:

package module_imp1;

sub foo {
print("Inside module_imp1::foon");
}

package module;
@ISA = (module_imp1);

package main;
module->foo();


C'est exactement ce que je veux faire, néanmoins cela oblige à
utiliser une syntaxe "objet" (->) alors que je travaille sur un
programme complètement orienté fonctions. :(



Je verrais plutôt quelque chose comme ça :
(suivant la valeur booléenne de $imp on sélectionne l'implémentation)

package module_imp1;
use strict;
use warnings;
use Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw( foo );

sub foo {
print "Inside module_imp1::foon";
}

1;
__END__

package module_imp2;
use strict;
use warnings;
use Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw( foo );

sub foo {
print "Inside module_imp2::foon";
}

1;
__END__

package module;
use Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw( foo );

my $imp = 0; # choix implémentation

if ($imp) {
require module_imp1;
module_imp1->import();
}
else {
require module_imp2;
module_imp2->import();
}

1;
__END__

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

use module;
foo();

__END__


HTH

--
J-L.M.
http://www.bribes.org/perl


Olivier Croquette
Le #1183177
Jean-Louis MOREL wrote, On 29/02/08 12:10:
if ($imp) {
require module_imp1;
module_imp1->import();
}
else {
require module_imp2;
module_imp2->import();
}


Super, c'est exactement ça que je m'imaginais.
Il me manquait juste le import. Je n'aurais pas imaginer qu'on puisse
injecter les symboles d'un paquet dans un autre aussi facilement.

Publicité
Poster une réponse
Anonyme