OVH Cloud OVH Cloud

Question sur les files handles

12 réponses
Avatar
Jean-Michel Caricand
Bonjour à tous,

Pourquoi peux t-on écrire

open $FILE, "<a.txt";
ou
open FILE, "<a.txt");

Dans certains codes, je vois le signe $ devant FILE et quelquefois non.
J'ai toujours écrit sans le $ mais j'aimerais conprendre le fin mot
de l'histoire. Y-a t-il une différence subtile ?

Merçi

10 réponses

1 2
Avatar
Emmanuel Florac
Le Mon, 20 Jun 2005 10:11:59 +0200, Jean-Michel Caricand a écrit :

J'ai toujours écrit sans le $ mais j'aimerais conprendre le fin mot
de l'histoire. Y-a t-il une différence subtile ?


il y a une différence très importante : FILE (sans $) est un descripteur
de fichier. Un descripteur de fichier a un scope global (où qu'il soit
défini il est accessible de partout dans le même programme).

$FILE vous devez sans doute le savoir, est une variable scalaire (c'est ce
qu'indique le $ en perl). Une variable scalaire a un scope local, elle
n'est accessible que dans le bloc où elle a été définie.

Que signifie l'utilisation d'une scalaire pour un descripteur de fichier?
Il y a deux possibilités : la plus courante, permise par les versions
récentes de perl, est l'utilisation d'un file descripteur anonyme, comme
ceci:

open my $FILE, "/un/chemin" or die " heu... !$ ?"

Avantage : la variable $FILE est locale, l'espace de nom global du
programme n'est pas pollué.
Autre possibilité (pour info, mieux vaut l'éviter) : on peut stocker le
"pointeur de nom" *FICHIER dans une scalaire :

my $f = *FICHIER ;

Dès lors, on pourra faire :

open $f, "/un/fichier"

et les deux blocs suivants auront le même effet :

while (<$f>) { .... }

while (<FICHIER>) { ... }

Parce que perl saura utiliser l'élément pointé par $f qui convient, à
savoir le descripteur de fichier FICHIER, la scalaire $FICHIER ou le
tableau @FICHIER selon le cas.
Cependant ce genre de bidouilles sombre généralement dans la magie
noire, et est un héritage du temps où on ne pouvait faire simplement

open my $f, "fichier"

qui est si commode.

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

Avatar
Jean-Michel Caricand


J'ai toujours écrit sans le $ mais j'aimerais conprendre le fin mot
de l'histoire. Y-a t-il une différence subtile ?



il y a une différence très importante : FILE (sans $) est un descripteur
de fichier. Un descripteur de fichier a un scope global (où qu'il soit
défini il est accessible de partout dans le même programme).

$FILE vous devez sans doute le savoir, est une variable scalaire (c'est ce
qu'indique le $ en perl). Une variable scalaire a un scope local, elle
n'est accessible que dans le bloc où elle a été définie.

Que signifie l'utilisation d'une scalaire pour un descripteur de fichier?
Il y a deux possibilités : la plus courante, permise par les versions
récentes de perl, est l'utilisation d'un file descripteur anonyme, comme
ceci:

open my $FILE, "/un/chemin" or die " heu... !$ ?"

Avantage : la variable $FILE est locale, l'espace de nom global du
programme n'est pas pollué.
Autre possibilité (pour info, mieux vaut l'éviter) : on peut stocker le
"pointeur de nom" *FICHIER dans une scalaire :

my $f = *FICHIER ;

Dès lors, on pourra faire :

open $f, "/un/fichier"

et les deux blocs suivants auront le même effet :

while (<$f>) { .... }

while (<FICHIER>) { ... }

Parce que perl saura utiliser l'élément pointé par $f qui convient, à
savoir le descripteur de fichier FICHIER, la scalaire $FICHIER ou le
tableau @FICHIER selon le cas.
Cependant ce genre de bidouilles sombre généralement dans la magie
noire, et est un héritage du temps où on ne pouvait faire simplement

open my $f, "fichier"

qui est si commode.



Merçi Emmanuel pour l'excellente explication !


Avatar
Nicolas George
Emmanuel Florac wrote in message
:
Une variable scalaire a un scope local, elle
n'est accessible que dans le bloc où elle a été définie.


Attention, il y a encore des gens qui n'utilisent pas use strict, et
d'autres qui utilisent encore use vars.

Avatar
Paul Gaborit
À (at) Mon, 20 Jun 2005 12:56:26 +0000 (UTC),
Nicolas George <nicolas$ écrivait (wrote):
Emmanuel Florac wrote in message
:
Une variable scalaire a un scope local, elle
n'est accessible que dans le bloc où elle a été définie.


Attention, il y a encore des gens qui n'utilisent pas use strict, et
d'autres qui utilisent encore use vars.


Le problème en Perl est qu'il existe deux notions plus ou moins distinctes :
la notion de variables lexicales ou globales d'une part et la notion de portée
des noms de variables d'autre part. C'est un héritage historique difficile à
expliquer.

Pour simplifier les choses, avec les version récentes de Perl et pour un
script de plus de n lignes (la limite n est arbitraire et dépend du
programmeur), on conseille donc effectivement à tout le monde l'utilisation de
'use strict;', 'my' et 'our' ainsi que la lecture (au minimum) de :

<http://perl.enstimac.fr/ModulesFr/Les_espaces_de_nom.html>

PS: l'usage de 'local' est réservé au programmeur chevronné. ;-)

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


Avatar
Emmanuel Florac
Le Mon, 20 Jun 2005 11:23:31 +0200, Jean-Michel Caricand a écrit :


Merçi Emmanuel pour l'excellente explication !


Je vous en prie :)
--
In girum imus nocte ecce et consumimur igni

Avatar
Emmanuel Florac
Le Mon, 20 Jun 2005 12:56:26 +0000, Nicolas George a écrit :


Attention, il y a encore des gens qui n'utilisent pas use strict, et
d'autres qui utilisent encore use vars.


Oui mais c'est MAL. Surtout ne pas utiliser 'use strict'. C'est quasiment
criminel (sauf dans un uneligne ou un obfu).

--
Quidquid latine dictum sit, altum sonatur

Avatar
Emmanuel Florac
Le Mon, 20 Jun 2005 16:59:52 +0200, Paul Gaborit a écrit :


Le problème en Perl est qu'il existe deux notions plus ou moins
distinctes : la notion de variables lexicales ou globales d'une part et la
notion de portée des noms de variables d'autre part. C'est un héritage
historique difficile à expliquer.


Je ne vois pas bien en quoi ces deux notions sont distinctes...

--
Mais monsieur, voudriez-vous que je me l'écorchasse?
Barbey d'Aurevilly.

Avatar
Paul Gaborit
À (at) Mon, 20 Jun 2005 22:06:29 +0200,
Emmanuel Florac écrivait (wrote):
Le Mon, 20 Jun 2005 16:59:52 +0200, Paul Gaborit a écrit :


Le problème en Perl est qu'il existe deux notions plus ou moins
distinctes : la notion de variables lexicales ou globales d'une part et la
notion de portée des noms de variables d'autre part. C'est un héritage
historique difficile à expliquer.


Je ne vois pas bien en quoi ces deux notions sont distinctes...


Juste un exemple...
------------------------------------------------------------
#!/usr/bin/perl -w
use strict;
package essai;
our $c = 2;
{
our $b = 1;
}
print "b: $b, c: $cn";
package main;
print "b: $b, c: $cn"; # ici $c est ok, $b n'est pas ok
------------------------------------------------------------

La variable $c n'a pas la même portée que la variable $b. Pourtant, elles sont
bien toutes les deux globales. Il y a d'autres exemples avec les variables
lexicales et les closures (sub anonymes). Les deux notions ne sont pas
évidemment pas conmplètement distinctes... Elles sont même très liées mais pas
toujours comme on pourrait le croire.

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


Avatar
Jean-Philippe Caruana


Attention, il y a encore des gens qui n'utilisent pas use strict, et
d'autres qui utilisent encore use vars.



Oui mais c'est MAL. Surtout ne pas utiliser 'use strict'. C'est quasiment
criminel (sauf dans un une ligne ou un obfu).


je ne comprends pas ton propos : qu'est-ce qui est mal ? ne pas utiliser
'use strict' (ce avec quoi je suis d'accord) ou alors il faut lire
"Surtout ne pas utiliser 'use strict'" comme une injonction (auquel cas,
je veux qu'on m'explique toutes ces contradictions) ?


--
jpc
http://perso.enstimac.fr/~caruana/


Avatar
Emmanuel Florac
Le Tue, 21 Jun 2005 11:11:43 +0200, Jean-Philippe Caruana a écrit :


je ne comprends pas ton propos : qu'est-ce qui est mal ? ne pas utiliser
'use strict' (ce avec quoi je suis d'accord) ou alors il faut lire


En fait il manque "de". C'est mal, surtout "de ne pas utiliser 'use
strict'". Désolé pour la mistoufle :)

"Surtout ne pas utiliser 'use strict'" comme une injonction (auquel cas,
je veux qu'on m'explique toutes ces contradictions) ?


Il FAUT utiliser 'use strict'.

Donc mes conseils :
1) Toujours utiliser 'use strict'.

2) Toujours utiliser 'use warnings' (ou perl -w), même en production
(perl -w pose des problèmes en production avec certains modules,
attention).
En quoi "use warnings" est si important? Très simple : il oblige à
contrôler les entrées un maximum. C'est souvent fastidieux, ça alourdit
le code, ça le ralentit un peu, MAIS ça retire la plupart des bugs
potentiels avant qu'on ait eu l'occasion de les rencontrer.

2.5) si on débute on peut aussi utiliser "use diagnostics". C'est souvent
pratique.

3) Compiler le code souvent. J'écris 2, 3 lignes de code, je compile.
S'il y a des erreurs ou des warnings, je corrige immédiatement. Le code
n'est jamais "en vrac".

4) Tester, débugger au maximum. Ne pas écrire plus de 10 lignes de code
sans tester, debugger. En revenant dessus plus tard ce sera d'autant plus
compliqué à débugger qu'il y a un gros morceau de code à tester.
Pour les fonctions ou méthodes, mettez les dans des modules, et écrivez
un script de test pour tester les entrées/sorties de chaque fonction. Il
y a des modules pour automatiser ça sur CPAN.

5) Refactoriser le code régulièrement. Maintenant on a un outil
fabuleux, Devel::Refactor. Il transforme le code en subs automatiquement,
avec une macro de son éditeur favori... N'oubliez pas: si une fonction
est plus grande qu'une page, il faut la diviser, y compris et surtout si
c'est le "main" du programme.

En appliquant ces méthodes on peut écrire des programmes de milliers de
lignes en quelques semaines, sans bugs ou presque.

--
Quidquid latine dictum sit, altum sonatur

1 2