OVH Cloud OVH Cloud

limiter le nombre de méthodes

12 réponses
Avatar
Paul
Bonjour,

je souhaite limiter mes lignes de codes, et je ne connais pas trop
Perl.
Si j'ai ces variables :

$var1 =3D "toto";
$var2 =3D "tata";

et ensuite j'ai 2 m=E9thodes comme ceci :
sub getVar1 {
return $var1;
}
sub getVar2 {
return $var2;
}

Est-il possible de passer le nom de la variable en param=E8tre afin de
n'avoir plus qu'une seule m=E9thode, un peu comme ceci :

sub get_A_Var {
my ($varname) =3D @_; # le nom de la variable que je souhaite obtenir
return ???????;
}

donc, il me resterai plus qu'a toujours appeler la m=EAme m=E9thode
get_A_Var() en lui sp=E9cifiant quelle variable je souhaite obtenir :
get_A_Var("var1"), me retournerai "toto"

Merci de votre aide. J'spere avoir =E9t=E9 assez clair dans mes
explications.

10 réponses

1 2
Avatar
Laurent Wacrenier
Paul écrit:
et ensuite j'ai 2 méthodes comme ceci :
sub getVar1 {
return $var1;
}


Une methode s'applique sur un objet, pas sur l'environement global.

sub getVar2 {
return $var2;
}

Est-il possible de passer le nom de la variable en paramètre afin de
n'avoir plus qu'une seule méthode, un peu comme ceci :

sub get_A_Var {
my ($varname) = @_; # le nom de la variable que je souhaite obtenir
return ???????;
}


Quel interêt ?

S'il y en a un : perldoc -f eval

Avatar
Paul
Une methode s'applique sur un objet, pas sur l'environement global.


Oui, je suis dans un package, je fais fausse route ? (car je prends
toutes les remarques car je suis débutant !)

Quel interêt ?
cela m'éviterai d'avoir

sub getVar1 {
return $var1;
}
sub getVar2 {
return $var2;
}
sub getVar3 {
return $var3;
}
et ainsi de suite pour mes 30 variables de mon objet

S'il y en a un : perldoc -f eval
je me plonge dans la doc... un long pavé pour eval !!


Avatar
Jérémy JUST
On 9 Jul 2005 05:18:39 -0700
"Paul" wrote:

Est-il possible de passer le nom de la variable en paramètre afin de
n'avoir plus qu'une seule méthode, un peu comme ceci :


Oui, en définissant une méthode « AUTOLOAD ».
Cette méthode est appelée dès qu'on appelle une méthode inexistante,
et le nom sous lequel elle a été appelé est dans la variable $AUTOLOAD.

Ça te permettra de faire exactement ce que tu veux, mais il faudra
gérer soigneusement les erreurs.


Merci de votre aide.


Je n'ai pas en tête de pointeurs vers de la doc. Je crois que les
chapitres de la PerlDoc relatifs aux objets donnent plusieurs exemples.

--
Jérémy JUST

Avatar
Nicolas George
"Paul" wrote in message
:
Oui, je suis dans un package, je fais fausse route ? (car je prends
toutes les remarques car je suis débutant !)


Dans un package, il y a des sous-routines, aussi appelées fonctions.

cela m'éviterai d'avoir
<snip>

et ainsi de suite pour mes 30 variables de mon objet


Ça ne prend pas très longtemps à écrire, et ça permet d'expliciter ce qui
est accessible.

Sinon, il est possible de générer de manière procéduralement les fonctions,
avec un éval pour les définir, ou bien en les stockant dans le namespace
global. Mais c'est plus technique.

Avatar
Jacques Caron
Salut,

On 9 Jul 2005 06:47:26 -0700, Paul wrote:

et ainsi de suite pour mes 30 variables de mon objet


Voir du côté de perldoc perltoot, descendre à AUTOLOAD: Proxy Methods

Jacques.

Avatar
Emmanuel Florac
Le Sat, 09 Jul 2005 15:53:34 +0200, Jérémy JUST a écrit :

Oui, en définissant une méthode « AUTOLOAD ». Cette méthode est
appelée dès qu'on appelle une méthode inexistante,
e


Les mecs, il a dit qu'il est débutant et vous qu'est ce que vous lui
conseillez? AUTOLOAD? Vous êtes givrés ou quoi? Un mec débute et
cherche la réponse à une mauvaise question, et au lieu de lui dire qu'il
n'est peut-être pas parti au départ dans la bonne direction, vous lui
expliquez comment se faire pêter la tête en utilisant une des
fonctionnalités les plus pointues, les plus dangereuses et les plus
complexes de Perl...

Bon, Paul, écoute, AUTOLOAD c'est extraordinaire mais c'est
rigoureusement réservé aux gourous. Je fais du Perl depuis 1996, je
connais AUTOLOAD et je sais comment ça marche, mais je n'ai jamais eu à
l'utiliser et à moins de devoir implémenter un modèle objet
fabuleusement complexe je ne vois pas pourquoi je l'utiliserais...

Pour en revenir à ton problème d'accesseur, il y a plusieurs solutions.
La méthode classique d'implémentation des objets en Perl utilise non pas
des scalaires, mais des hashs:

package foo;

sub new {
my %foo = {toto => '', tata=> '' }; return bless %foo;
}

Ce qui permet de faire un accesseur universel facilement :

sub get_param {
my $self = shift ; # jé récupère la référence de l'objet
my $param = shift;
return $self->{$param}
}

Donc en appelant "$foo->get_param(toto) je récupère la valeur du
paramètre en question.

Il existe d'autres méthodes pour construire des objets en perl bien sûr
(TIMTOWTDI est la devise de perl) mais celle ci est la méthode
"canonique". Il est conseillé quand on débute d'utiliser celle-ci, même
si elle a ses inconvénients.

Si pour une raison quelconque tu voulais tout de même utiliser des
scalaires pour tes objets, dans ce cas tu pourrais créer un hash
contenant les références à ces scalaires pour pouvoir les appeler.
C'est une approche potentiellement intéressante parce qu'elle évite le
problème de la faute de frappe dans les clefs de hash (qui ne sont pas
interceptées par "use strict;" hélas).

Un truc comme ça :

package foo;

sub new {
my ($toto, $tatat, $titi, $tutu);
my %foo = {toto => $toto, tata=> $tata, titi=>$titi, tutu => $tutu };

return bless %foo;
}

sub set_param {
my $self = shift;
my ($param, $value) = @_;

# le déréférencement de la scalaire est clair avec cette syntaxe
# notez l'utilisation de "and" et surtout pas "&&"
${$self->{$param}} = $value and return 1;

# là on renvoie "faux" si on n'a pas pu attribuer le paramètre
# parce que la scalaire n'existe pas, par exemple (faute de frappe...)
return;
}

Attention, je n'ai pas testé ce code mais je pense qu'il est correct...
En plus, il est lisible, compréhensible et "sans magie" contrairement à
des bidouilles avec AUTOLOAD qui sont presque toujours incompréhensibles
au premier coup d'oeil.

--
Il y a toujours un bug de plus.
Loi de Lubarsky.

Avatar
Michel Rodriguez
Paul wrote:
Bonjour,

je souhaite limiter mes lignes de codes, et je ne connais pas trop
Perl.
Si j'ai ces variables :

$var1 = "toto";
$var2 = "tata";

et ensuite j'ai 2 méthodes comme ceci :
sub getVar1 {
return $var1;
}
sub getVar2 {
return $var2;
}

Est-il possible de passer le nom de la variable en paramètre afin de
n'avoir plus qu'une seule méthode, un peu comme ceci :

sub get_A_Var {
my ($varname) = @_; # le nom de la variable que je souhaite obtenir
return ???????;
}

donc, il me resterai plus qu'a toujours appeler la même méthode
get_A_Var() en lui spécifiant quelle variable je souhaite obtenir :
get_A_Var("var1"), me retournerai "toto"

Merci de votre aide. J'spere avoir été assez clair dans mes
explications.

C'est un probleme que tu ne devrais pas etre pas le seul a avoir, donc

un petit tour syr CPAN done Class::Accessor, qui cree automatiquement
des accesseurs (?) sur les objets.

http://search.cpan.org/~kasei/Class-Accessor-0.19/

--
mirod

Avatar
Emmanuel Florac
Le Sat, 09 Jul 2005 18:27:29 +0200, Emmanuel Florac a écrit :

Attention, je n'ai pas testé ce code mais je pense qu'il est correct...


Il ne l'est pas, cependant celui-ci produit les résultats escomptés :

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;


package foo;

sub new {
my ($toto, $tata, $titi, $tutu);
my %foo = ( toto => $toto, tata=> $tata, titi=>$titi, tutu => $tutu );

return bless %foo;
}

sub set_param {
my $self = shift;
my ($param, $value) = @_;

# le déréférencement de la scalaire est clair avec cette syntaxe
if (ref $self->{$param} ) {
${$self->{$param}} = $value;
return 1;
}
# là on renvoie "faux" si on n'a pas pu attribuer le paramètre
# parce que la scalaire n'existe pas, par exemple (faute de frappe...)
return;
}

sub get_param {
my $self = shift;
my $param = shift;

if (ref $self->{$param}) { return ${$self->{$param}} }

return;
}


package main;

my $obj = foo->new();

print Dumper($obj);

foreach ( qw(toto tata titi tutu tete)) {
$obj->set_param($_, 42) or print "impossible de définir $_n";
}

foreach ( qw(toto tata titi tutu tete)) {
if ($obj->get_param($_)) {
print "$_ : ",$obj->get_param($_), "n" ;
} else {
print "param $_ indéfinin"
}
}

print Dumper($obj);

--
Le travail est la malédiction des classes qui boivent.
O. Wilde.

Avatar
Paul
Merci de vos réponses à tous, effectivement, je pense que la méthode
proposée avec AUTOLOAD sera trop complexe pour moi.

merci encore à tous.


Le Sat, 09 Jul 2005 18:27:29 +0200
Emmanuel Florac vous écriviez :

Le Sat, 09 Jul 2005 15:53:34 +0200, Jérémy JUST a écrit :

Oui, en définissant une méthode « AUTOLOAD ». Cette méthode est
appelée dès qu'on appelle une méthode inexistante,
e


Les mecs, il a dit qu'il est débutant et vous qu'est ce que vous lui
conseillez? AUTOLOAD? Vous êtes givrés ou quoi? Un mec débute et
cherche la réponse à une mauvaise question, et au lieu de lui dire
qu'il

n'est peut-être pas parti au départ dans la bonne direction, vous lui
expliquez comment se faire pêter la tête en utilisant une des
fonctionnalités les plus pointues, les plus dangereuses et les plus
complexes de Perl...

Bon, Paul, écoute, AUTOLOAD c'est extraordinaire mais c'est
rigoureusement réservé aux gourous. Je fais du Perl depuis 1996, je
connais AUTOLOAD et je sais comment ça marche, mais je n'ai jamais eu
à

l'utiliser et à moins de devoir implémenter un modèle objet
fabuleusement complexe je ne vois pas pourquoi je l'utiliserais...

Pour en revenir à ton problème d'accesseur, il y a plusieurs
solutions.

La méthode classique d'implémentation des objets en Perl utilise non
pas

des scalaires, mais des hashs:

package foo;

sub new {
my %foo = {toto => '', tata=> '' }; return bless %foo;
}

Ce qui permet de faire un accesseur universel facilement :

sub get_param {
my $self = shift ; # jé récupère la référence de l'objet
my $param = shift;
return $self->{$param}
}

Donc en appelant "$foo->get_param(toto) je récupère la valeur du
paramètre en question.

Il existe d'autres méthodes pour construire des objets en perl bien sû
r

(TIMTOWTDI est la devise de perl) mais celle ci est la méthode
"canonique". Il est conseillé quand on débute d'utiliser celle-ci, m ê
me

si elle a ses inconvénients.

Si pour une raison quelconque tu voulais tout de même utiliser des
scalaires pour tes objets, dans ce cas tu pourrais créer un hash
contenant les références à ces scalaires pour pouvoir les appeler.
C'est une approche potentiellement intéressante parce qu'elle évite le
problème de la faute de frappe dans les clefs de hash (qui ne sont pas
interceptées par "use strict;" hélas).

Un truc comme ça :

package foo;

sub new {
my ($toto, $tatat, $titi, $tutu);
my %foo = {toto => $toto, tata=> $tata, titi=>$titi, tutu =>
$tutu };


return bless %foo;
}

sub set_param {
my $self = shift;
my ($param, $value) = @_;

# le déréférencement de la scalaire est clair avec cette syntaxe
# notez l'utilisation de "and" et surtout pas "&&"
${$self->{$param}} = $value and return 1;

# là on renvoie "faux" si on n'a pas pu attribuer le paramètre
# parce que la scalaire n'existe pas, par exemple (faute de
frappe...)

return;
}

Attention, je n'ai pas testé ce code mais je pense qu'il est
correct...

En plus, il est lisible, compréhensible et "sans magie" contrairement
à

des bidouilles avec AUTOLOAD qui sont presque toujours incompré
hensibles

au premier coup d'oeil.

--
Il y a toujours un bug de plus.
Loi de Lubarsky.




Avatar
Klaus Eichner
"Paul" wrote in message
news:

Bonjour,

je souhaite limiter mes lignes de codes, et je ne connais pas trop
Perl.
Si j'ai ces variables :

$var1 = "toto";
$var2 = "tata";

et ensuite j'ai 2 méthodes comme ceci :
sub getVar1 {
return $var1;
}
sub getVar2 {
return $var2;
}

Est-il possible de passer le nom de la variable en paramètre afin de
n'avoir plus qu'une seule méthode, un peu comme ceci :

sub get_A_Var {
my ($varname) = @_; # le nom de la variable que je souhaite obtenir
return ???????;
}

donc, il me resterai plus qu'a toujours appeler la même méthode
get_A_Var() en lui spécifiant quelle variable je souhaite obtenir :
get_A_Var("var1"), me retournerai "toto"


Je propose un simple eval:
===============================
use strict;
use warnings;

my $var1 = "toto";
my $var2 = "tata";

print "$var1 = '".get_A_Var('$var1')."'n";
print "$var2 = '".get_A_Var('$var2')."'n";
print "$var3 = '".get_A_Var('$var3')."'n";
print "del *.* = '".get_A_Var('del *.*')."'n";

sub get_A_Var {
# avant faire un 'eval', il vaut mieux vérifier que $_[0] correspond
bien à un nom d'une variable
unless ($_[0] =~ /^$w+$/) { die "Get_A_Var: Parametre '$_[0]' n'est
pas une variable" };
return eval("$_[0]");
}
=================================
Merci de votre aide. J'spere avoir été assez clair dans mes
explications.


--
Klaus

1 2