Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Constante

4 réponses
Avatar
Luc Martineau
Bonjour,

Je suis en train de me faire une bibliothèques de fonctions.
Dans cette bibliothèque, j'ai besoin de définir quelques valeurs constantes


Donc dans ma bibliothèque, fct.pl, j'ai ajouté:

use constant MA_CONSTANTE => 'une valeur';

Je peux ensuite utiliser MA_CONSTANTE dans ma bibliothèque.

Par contre, je n'arrive pas à utiliser cette constante dans un programme qui
importe cette bibliothèque.
require "/mon_chemin/fct.pl";


Pour ce faire, je déclare ma constante de cette façon dans ma bibiothèque

sub MA_CONSTANTE () { une valeur' }

Je n'ai qu'à utiliser MA_CONSTANTE avec des ()

if( $var eq MA_CONSTANTE() ) {
...
}


C'est correct de déclarer une sous-routine pour l'utiliser comme constante ?
Comment faire pour que MA_CONSTANTE soit disponible après importation en la
déclarant avec use constant?

Merci

Luc

4 réponses

Avatar
Jérémy JUST
On Wed, 21 Apr 2004 00:05:24 -0400
Luc Martineau wrote:

use constant MA_CONSTANTE => 'une valeur';
Je peux ensuite utiliser MA_CONSTANTE dans ma bibliothèque.

Par contre, je n'arrive pas à utiliser cette constante dans un programme
qui importe cette bibliothèque.
require "/mon_chemin/fct.pl";


Les constantes s'appellent comme les variables: si elles ont été
déclarées dans un autre package, il faut donner leur nom complet (ou les
exporter):

print malib::MA_CONSTANTE


sub MA_CONSTANTE () { une valeur' }

C'est correct de déclarer une sous-routine pour l'utiliser comme
constante ?


Disons que ça fonctionne, mais ce n'est pas très efficace. C'est un
appel de fonction qui ne sert pas à grand chose.

Note que les constantes ne sont pas tellement utilisées en Perl. Elles
n'ont pas réellement d'avantages sur les variables (pour peu qu'on se
discipline un peu et qu'on n'essaie pas de les écraser).

--
Jérémy JUST

Avatar
Paul GABORIT
À (at) Wed, 21 Apr 2004 21:11:50 +0200,
Jérémy JUST écrivait (wrote):
On Wed, 21 Apr 2004 00:05:24 -0400
Luc Martineau wrote:

use constant MA_CONSTANTE => 'une valeur';
Je peux ensuite utiliser MA_CONSTANTE dans ma bibliothèque.

Par contre, je n'arrive pas à utiliser cette constante dans un programme
qui importe cette bibliothèque.
require "/mon_chemin/fct.pl";


Les constantes s'appellent comme les variables: si elles ont été
déclarées dans un autre package, il faut donner leur nom complet (ou les
exporter):

print malib::MA_CONSTANTE


Oui. On peut aussi exporter la constante...mais ce n'est pas propre. Dans tous
les cas, on perd le gain de performance amené par le compilateur.


sub MA_CONSTANTE () { une valeur' }

C'est correct de déclarer une sous-routine pour l'utiliser comme
constante ?


Disons que ça fonctionne, mais ce n'est pas très efficace. C'est un
appel de fonction qui ne sert pas à grand chose.


C'est exactement comme cela que fait *actuellement* le pragma 'constant'. La
partie importante est l'usage du prototype ().

Note que les constantes ne sont pas tellement utilisées en Perl. Elles
n'ont pas réellement d'avantages sur les variables (pour peu qu'on se
discipline un peu et qu'on n'essaie pas de les écraser).


C'est pratique pour programmer proprement.

De plus, cela permet au compilateur d'optimiser le code puisqu'il peut
pré-calculer beaucoup de choses.

Par exemple :

2*PI

sera pré-calculé une bonne fois pour toutes... alors que :

2*$PI

sera recalculé à chaque fois.


print "toton" if DEBUG;

le 'print' et le 'if' ne seront même plus dans le code généré si la constante
DEBUG vaut 0.

Tout cela, ce n'est malheureusement plus vrai si la constante ne fait pas
partie du même module et donc si le compilateur ne voit pas le prototype.

Dans les versions récentes de Perl, la notion de valeur non-modifiable
commence à être implémentée. À terme, le pragma 'constant' pourra utiliser ces
facilités pour améliorer encore le code dans tous les cas.

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>


Avatar
Paul GABORIT
À (at) Thu, 22 Apr 2004 15:14:19 +0200,
Paul GABORIT écrivait (wrote):
Dans les versions récentes de Perl, la notion de valeur non-modifiable
commence à être implémentée. À terme, le pragma 'constant' pourra utiliser
ces facilités pour améliorer encore le code dans tous les cas.


À noter aussi l'annonce du module Readonly en version 1.3. Dans certains cas,
ça peut remplacer 'constant'. La doc de Readonly contient d'ailleurs une
longue liste d'arguments pour ou contre les différentes solutions.

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
Jérémy JUST
On Thu, 22 Apr 2004 15:14:19 +0200
Paul GABORIT wrote:

sub MA_CONSTANTE () { une valeur' }
Disons que ça fonctionne, mais ce n'est pas très efficace. C'est un

appel de fonction qui ne sert pas à grand chose.
C'est exactement comme cela que fait *actuellement* le pragma

'constant'. La partie importante est l'usage du prototype ().


J'avoue n'avoir pas immédiatement fait confiance à ce que tu disais, et
j'ai vérifié empiriquement:

<<<<<
use constant C => 10000 ;
sub Fp () { 10000 } ;
sub Fn { 10000 } ;
my $Vi = 10000 ;
my $Ve = shift ;
my $j ;

my $res ;
for(my $i = 0 ; $i <= 100000 ; $i++)
{for($j = 0 ; $j <= 10000 ; $j++)
{$res = C + 2 ; #####
$res = C + 3 ; #####
}
}







J'ai exécuté ce programme en utilisant différentes variables/constantes
dans les lignes marquées de dièses:

C : constante
600.02 secondes

Fp : fonction avec prototype ()
619.32 secondes

Fn : fonction non prototypée
2152.57 secondes

Vi : variable à valeur constante et codée en dur
640.36 secondes

Ve : variable à valeur constante et passée en argument
643.30 secondes

j : variable euh... variable
633.26 secondes

Je m'attendais par exemple à voir une différence significative entre Vi
et Ve.


Par exemple :
2*PI
sera pré-calculé une bonne fois pour toutes... alors que :
2*$PI
sera recalculé à chaque fois.


Là, j'ai été surpris que le compilateur ne sachet pas « inliner » une
expression simple de ce genre. Mais ça semble tout à fait exact.


--
Jérémy JUST