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

require avec use strict et warnings

26 réponses
Avatar
Asterbing
Bonjour. Je reviens sur le sujet du require abordé dans un récent fil
parce que je n'y réussi pas.

Rappel : soit un script principal en perl (main.cgi) souhaitant utiliser
toutes les déclarations (constantes et variabbles) d'un fichier
modifiable par l'utilisateur (config.cgi). Je souhaitais incorporer
config.cgi dans main.cgi via une ligne "require 'config.cgi';", mais ça
me pose quelque problème. A noter que je teste sous ça dans un
environnement avec Perl Express comme IDE, ActivePerl comme interpréteur
Perl, le tout sous Windows.

Le souci vient du fait que je souhaite aussi mettre une ligne "use
strict;" et lancer le script avec warnings (-w) durant le développement.

Or, lorsque je vérifie la syntaxe dans PerlExpress (F12) avec "use
strict;" actif, le require semble ne pas fonctionner : j'obtiens une
erreur : "Global symbol '$STYPE' requires explicit package name at
main.cgi line 23." sur la première variable devant provenr de
config.cgi.

Si je retire "use strict;", le lien à config.cgi semble marcher (pas
d'erreur de var non déclarée), mais cette fois, c'est le -w qui me met
des warnings de type : "Name 'main::STATCOL' used only once: possible
typo at main.cgi line 240.".

Si je retire "use strict;" et "-w", tout va bien !

Ma question est donc : comment faire accepter ce "require
'config.cgi';" avec "use strict;" et le switch "-w" ?

10 réponses

1 2 3
Avatar
Emmanuel Florac
Le Wed, 15 Mar 2006 15:52:45 +0100, Asterbing a écrit :


Le souci vient du fait que je souhaite aussi mettre une ligne "use
strict;" et lancer le script avec warnings (-w) durant le développement.


À moins que tu ne sois contraint à utiliser une version de perl
antérieure à 5.6, utiliser "-w" est déconseillé. Mieux vaut utiliser

use warnings;

Si tu utilises "use strict", tu DOIS déclarer toutes tes variables avec
"my"(en général) ou "our" (rarement).
Si tu as des warnings, en général il y a presque toujours une bonne
raison; il ne faut surtout pas céder à la facilité et désactiver
strict et warnings sous prétexte que ça complique la vie, parce qu'en
fait c'est le contraire, ça t'oblige à corriger certains bugs avant
même que tu aies réalisé qu'ils en sont...

--
Si non confectus non reficiat.

Avatar
Asterbing
In article ,
says...
Le Wed, 15 Mar 2006 15:52:45 +0100, Asterbing a écrit :


Le souci vient du fait que je souhaite aussi mettre une ligne "use
strict;" et lancer le script avec warnings (-w) durant le développement.


À moins que tu ne sois contraint à utiliser une version de perl
antérieure à 5.6, utiliser "-w" est déconseillé. Mieux vaut utiliser

use warnings;



J(utilise -w simplement parce que c'est l'usage par défaut dans Perl
Express (l'IDE que j'utilise).

Si tu utilises "use strict", tu DOIS déclarer toutes tes variables avec
"my"(en général) ou "our" (rarement).


Toutes les variables de config.cgi sont déclarées avec "my".

Si tu as des warnings, en général il y a presque toujours une bonne
raison; il ne faut surtout pas céder à la facilité et désactiver
strict et warnings sous prétexte que ça complique la vie, parce qu'en
fait c'est le contraire, ça t'oblige à corriger certains bugs avant
même que tu aies réalisé qu'ils en sont...




Aucune intention d'enlever strict, n'aies crainte ;-) Bon, sinon, j'ai
cherché un peu dans google groups avec "perl require 'use strict' my" et
apparemment il ya toutes sortes de réponses : certain parlent de
mentionner explictement le package avec ::, d'autres d'utiliser
uniquement "our", d'autre de passer par "use lib" plutôt que "require",
d'autres de faire un BEGIN{require 'config.cgi'} pour faire que le
require soit considérer avant d'être au run-time, d'autre de faire de
l'export, d'autres de redéclarer les variables dans main.cgi, etc... Je
m'y perd !

Bon, si nous repartions d'un cas simple qui ne marche pas :

un config.cgi comme ça :
use strict;
my $WAY = 1;
1;

un main.cgi comme ça :
#!c:/perl/bin/Perl.exe
use strict;
require 'config.cgi';

if ($WAY == 1){
...;}

Ca me donne une erreur "Global symbol '$WAY' requires explicit package
name at main.cgi"


Avatar
Nicolas George
Asterbing wrote in message
:
J(utilise -w simplement parce que c'est l'usage par défaut dans Perl
Express (l'IDE que j'utilise).


Justement, mettre « use warnings » dans le script lui-même permet d'avoir un
fonctionnement indépendant de l'environnement d'exécution.

Toutes les variables de config.cgi sont déclarées avec "my".


Les variables déclarées avec my sont lexicales : en aucun cas elles ne
peuvent être visibles en dehors de leur bloc. Un fichier inclus avec do (qui
est la fonction derrière require) forme un bloc à lui tout seul, les
variables qui y sont déclarées avec my ne sont donc pas visibles en dehors.

certain parlent de
mentionner explictement le package avec ::,


C'est, d'une manière ou d'une autre, ce qu'il faut faire.

d'autres d'utiliser
uniquement "our",


C'est fondamentalement équivalent à la méthode précédente. Une variable
déclarée avec our désigne la variable du package courant, donc.

our $a;
$a = 42;

fait la même chose que :

$::a = 42;

si on est dans le package principal.

d'autre de passer par "use lib" plutôt que "require",


Rien à voir. use lib sert juste à ajouter des répertoires à la liste de ceux
où do/require va chercher ses fichiers.

d'autres de faire un BEGIN{require 'config.cgi'} pour faire que le
require soit considérer avant d'être au run-time,


Rien à voir, ça ne peut pas changer la visibilité des variables.

d'autre de faire de
l'export,


Export est une autre manière de manipuler explicitement l'appartenance des
variables aux packages, mais c'est de l'overkill ici.

d'autres de redéclarer les variables dans main.cgi,


Ça peut être utile.

my $WAY = 1;


$::WAY = 1;

ou

our $WAY = 1;

#!c:/perl/bin/Perl.exe


Toutes mes condoléances.

if ($WAY == 1){


if($::WAY == 1) {

ou

our $::WAY;
if($WAY == 1) {

Avatar
Asterbing
In article <dvaas5$1mtd$, nicolas$
s.org says...
Asterbing wrote in message
:
J(utilise -w simplement parce que c'est l'usage par défaut dans Perl
Express (l'IDE que j'utilise).


Justement, mettre « use warnings » dans le script lui-même permet d'avoir un
fonctionnement indépendant de l'environnement d'exécution.


Si ce n'est justement que je ne vois pas l'intérêt de conserver les
warnings pour le script final une fois uploadé sur le serveur final
(hors test et développement). Ainsi, le -w évite d'avoir à penser à
enlever un "use warnings" avant upload. A moins que tu m'expliques un
intérêt que j'aurais loupé.

Toutes les variables de config.cgi sont déclarées avec "my".


Les variables déclarées avec my sont lexicales : en aucun cas elles ne
peuvent être visibles en dehors de leur bloc. Un fichier inclus avec do (qui
est la fonction derrière require) forme un bloc à lui tout seul, les
variables qui y sont déclarées avec my ne sont donc pas visibles en dehors.



Alors pourquoi lorsque je laisse "my $WAY = 1;" dans config.cgi et
l'utilise avec $::WAY dans main.cgi, ça marche ?

certain parlent de mentionner explictement le package avec ::,


C'est, d'une manière ou d'une autre, ce qu'il faut faire.


Oui, compris, mais quel est la manière la plus simple de le faire.
L'ajout de :: partout dans mon main.cgi risque d'être laborieux et
d'énormément alourdir l'aspect du code. N'y a-t-il pas un moyen plus
élégant ?

d'autres d'utiliser uniquement "our",

C'est fondamentalement équivalent à la méthode précédente. Une variable
déclarée avec our désigne la variable du package courant, donc.

our $a;
$a = 42;

fait la même chose que :

$::a = 42;



Ou "our $a = 42;" donc. Tu mets d'ailleurs ça un peu plus loin dans ton
post de réponse.

d'autre de passer par "use lib" plutôt que "require",

Rien à voir. use lib sert juste à ajouter des répertoires à la liste de ceux
où do/require va chercher ses fichiers.



C'est ce que je m'étais dit, mais c'est apparemment très répandu si j'en
crois les archives Google Groups. Enfin, de toute façon, ça ne
m'intéresse pas parce que, à moins d'avoir loupé un truc, je crois que
le "use lib" réclame le chemin complet absolu vers le module... Ce qui
forcerait à intervenir dans main.cgi à chaque install pour l'adapter à
l'arborescence particulière du serveur visé : ce que je ne souhaite pas.

d'autres de faire un BEGIN{require 'config.cgi'} pour faire que le
require soit considérer avant d'être au run-time,


Rien à voir, ça ne peut pas changer la visibilité des variables.


OK ! Il y a donc à boire et à manger dans les archives. Que les
brouilleurs de pistes lèvent la souris.

d'autre de faire de l'export,

Export est une autre manière de manipuler explicitement l'appartenance des
variables aux packages, mais c'est de l'overkill ici.


Oui, j'ai eu un peu peur quand j'ai lu ça et le détail qui suivait :
glurp !

d'autres de redéclarer les variables dans main.cgi,

Ça peut être utile.


N'est-ce pas là, peut-être un chemin pour éviter les innombrable :: dans
main.cgi ? Pas sûr de ce que je dis, alors je ne m'étend pas ;-) Si
c'est une connerie, désolé.

#!c:/perl/bin/Perl.exe


Toutes mes condoléances.


Tiens, à ce sujet, n'existe-il pas une astuce pour faire que cette
déclaration du chemin interpréteur soit dépendant de l'OS. Je veux dire
que le script switch automatiquement de "#!c:/perl/bin/Perl.exe" à
"#!/usr/bin/perl" selon qu'il s'éxécute ss Win32 ou Unix[-like] ? Ceci,
bien sûr, sans parler d'une moulinette pré-upload.

if($::WAY == 1) {


Oui, que ce soit avec "my $WAY = 1;" ou "our $WAY = 1;" dans config.cgi,
ça marche avec ce $::WAY dans main.cgi. D'où ma question en haut de ce
post : n'y a-t-il pas une écriture plus légère (sans ces nombreux :: ds
main.cgi) ?

our $::WAY;
if($WAY == 1) {


Si je fais le "our $::WAY" ds config.cgi et l'usage if($WAY == 1) dans
main.cgi, non, ça ne marche pas.

En résumé :
- Pourquoi peut-on mettre our/my sans que ça change quoi que ce soit ?
- La sol. our/my ds config.cgi et :: ds main.cgi marche. Plus simple ?


Avatar
Asterbing
In article ,
says...
Ma question est donc : comment faire accepter ce "require
'config.cgi';" avec "use strict;" et le switch "-w" ?



Peut-être une autre piste pas encore essayée (pas devant la station de
dev là) : mettre tout le contenu de config.cgi en constantes plutôt que
variables.

[my|our] $WAY = 1;

devient donc :

use constant WAY => 1;

Qu'en pensez-vous ? En dehors du fait qu'une constante ne peut ensuite
être modifiée, nous sommes d'accord (moi pas débile quand même ;-))

Avatar
Asterbing
In article ,
says...

En résumé :
- Pourquoi peut-on mettre our/my sans que ça change quoi que ce soit ?
- La sol. our/my ds config.cgi et :: ds main.cgi marche. Plus simple ?



Bon, je reviens parce que j'ai trois : celle déjà dite ds post précédent
avec ::, celle via constantes exprimée au niveau 2 du fil, une nouvelle
via use vars.

Je résume :

1) "[our|my] $WAY = 1; "ds config.cgi et "$::WAY" dans main.cgi

2) "use constant WAY => 1;" ds config.cgi et "WAY" dans main.cgi

3) "[our|my] $WAY = 1;" ds config.cgi, "use vars qw($ALLOW_IMG);" et
"$WAY" ds main.cgi

Qu'en pensez-vous ? Avantage/inconvénient de chaque méthode ? Avez-vous
des réticences sur l'une d'elles ? Avez-vous d'autres voies ?

Aussi, reste le truc sur my ou our. Les deux ont un scope niveau fichier
dans la mesure où la déclaration n'est pas dans un sub ou autre bloc...
Alors, quelle est la différence ? Je reste dans le brouillard sur ce
sujet.

Avatar
Rue des Prairies
In article <dvaas5$1mtd$, nicolas$
s.org says...
Asterbing wrote in message
:

#!c:/perl/bin/Perl.exe
Toutes mes condoléances.



Tiens, à ce sujet, n'existe-il pas une astuce pour faire que cette
déclaration du chemin interpréteur soit dépendant de l'OS. Je veux dire
que le script switch automatiquement de "#!c:/perl/bin/Perl.exe" à
"#!/usr/bin/perl" selon qu'il s'éxécute ss Win32 ou Unix[-like] ? Ceci,
bien sûr, sans parler d'une moulinette pré-upload.



Bonjour,

Il suffit d'installer Perl dans c:usr au lieu de c:perl
et tu pourras utiliser #!/usr/bin/perl

Olivier.



Avatar
Asterbing
In article <441928a3$0$18309$,
says...
Il suffit d'installer Perl dans c:usr au lieu de c:perl
et tu pourras utiliser #!/usr/bin/perl




Bonne idée ! Seul doute : l'environnement est dupliqué sur 3 stations
ayant chacune plusieurs disques et plus encore de partitions, et je ne
suis pas certain que tout soit installé au même endroit sur chacune (par
exemple, sur la station sur laquelle je suis aujourd'hui, perl est sur
C: et l'IDE sur E: : ce qui fait qu'un / ferait référence au racine de
E: pour lui). Bon, faudrait réinstaller les trois machines (de la
discussion dans l'air).

Avatar
Rue des Prairies
In article <441928a3$0$18309$,
says...
Il suffit d'installer Perl dans c:usr au lieu de c:perl
et tu pourras utiliser #!/usr/bin/perl




Bonne idée ! Seul doute : l'environnement est dupliqué sur 3 stations
ayant chacune plusieurs disques et plus encore de partitions, et je ne
suis pas certain que tout soit installé au même endroit sur chacune (par
exemple, sur la station sur laquelle je suis aujourd'hui, perl est sur
C: et l'IDE sur E: : ce qui fait qu'un / ferait référence au racine de
E: pour lui). Bon, faudrait réinstaller les trois machines (de la
discussion dans l'air).


Ça demande confirmation mais je viens de faire un test d'exécution d'un
script qui se trouve sur un disque différent de celui où est Perl, ça
fonctionne très bien.
Il ne te reste qu'à tester.

Olivier.


Avatar
Asterbing
In article <441928a3$0$18309$,
says...
Il suffit d'installer Perl dans c:usr au lieu de c:perl
et tu pourras utiliser #!/usr/bin/perl



Je viens de parler avec le sysadmin : y a aussi linkd.exe livré avec le
reskit win 2003 (dispo gratuit sur le site ms) qui permet de faire un
lien entre un chemin et un autre, pourvu que ce soit sur deux disques
différents et qu'ils soient en NTFS.

1 2 3