OVH Cloud OVH Cloud

références, chaînes, descripteurs de fichiers et tutti quanti..

5 réponses
Avatar
Emmanuel Florac
Je voulais utiliser un tableau pour créer des descripteurs de fichiers,
et nommer dynamiquement des variables, comme ça :

@liste=("titi","tata","toto");
foreach (@liste) {open $_, "<$_.txt" ; $$_ = join('', <$_>)}

Ça marche, mais pas si on rajoute "use strict":

Can't use string ("titi") as a symbol ref while "strict refs" in use at -
line 3

Donc, question à la con... Comment fait-on? J'ai utilisé un hash à la
place, comme ça :

my %liste=('titi'=>'','tata'=>'','toto'=>'');
foreach (keys %liste) {open TT, "<$_.txt" ; $liste{$_} = join('', <TT>)}

Mais je trouve la première solution plus jolie :), j'aimerais l'affiner
:) Est-ce que

my @liste=(*titi,*tata,*toto);

je peux m'en sortir (le problème c'est les main:: partout...)? Voyez-vous
une façon plus atrocement perlienne de faire?

--
Toutes les organisations ont leur règles, et les Femmes Algériennes
doivent avoir aussi leurs règles.
Kaid Ahmed.

5 réponses

Avatar
Jérémy JUST
On Mon, 04 Oct 2004 23:37:59 +0200
Emmanuel Florac wrote:

@liste=("titi","tata","toto");
foreach (@liste) {open $_, "<$_.txt" ; $$_ = join('', <$_>)}

Ça marche, mais pas si on rajoute "use strict":

Can't use string ("titi") as a symbol ref while "strict refs" in use


C'est normal: le « use strict » est là pour t'empêcher de faire des
bêtises! :)
Si tu y tiens, tu peux le désactiver localement: dans le bloc où tu
veux laisser libre court à ta verve perverse, utilise:

no strict refs ;


J'ai utilisé un hash à la place, comme ça :

my %liste=('titi'=>'','tata'=>'','toto'=>'');
foreach (keys %liste) {open TT, "<$_.txt" ; $liste{$_} = join('',
<TT>)}


Ça me semble beaucoup plus idiomatique en Perl. Les hashes permettent
de faire ce que tu veux faire simplement, alors pourquoi chercher à les
contourner?

Dans ton cas, tu ne risques pas grand chose, mais il m'est arrivé
qu'un programme plante au bout de 10 heures de calculs parce que j'avais
voulu faire le malin avec les noms dynamiques de fonctions, que j'ai eu
les doigts malhabiles et que le compilateur n'a pas trouvé ma faute de
frappe (forcément: je lui avait demandé de me laisser tranquille).



Ah, au passage, fais attention si tu as beaucoup de fichiers ouverts
en même temps. Le système peut te refuser d'en ouvrir plus de 256
(suivant l'OS et la configuration locale).
Si tu peux, ferme-les; ou bien envisage d'utiliser:

use FileCache ;

--
Jérémy JUST

Avatar
Emmanuel Florac
Le Tue, 05 Oct 2004 01:04:10 +0200, Jérémy JUST a écrit :


Dans ton cas, tu ne risques pas grand chose, mais il m'est arrivé
qu'un programme plante au bout de 10 heures de calculs parce que j'avais
voulu faire le malin avec les noms dynamiques de fonctions


En fait dans ce cas précis ce qui m'amuserait ce serait de nommer
dynamiquement les variables, plutôt :) Dans ce cas aussi tu trouves plus
"perlien" de faire un bête hash?

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

Avatar
Paul Gaborit
À (at) Mon, 04 Oct 2004 23:37:59 +0200,
Emmanuel Florac écrivait (wrote):
Je voulais utiliser un tableau pour créer des descripteurs de fichiers,
et nommer dynamiquement des variables, comme ça :

@liste=("titi","tata","toto");
foreach (@liste) {open $_, "<$_.txt" ; $$_ = join('', <$_>)}

Ça marche, mais pas si on rajoute "use strict":

Can't use string ("titi") as a symbol ref while "strict refs" in use at -
line 3


L'utilisation des références symboliques n'est jamais une bonne solution (même
si elle parait plus simple à première vue).

Donc, question à la con... Comment fait-on? J'ai utilisé un hash à la
place, comme ça :

my %liste=('titi'=>'','tata'=>'','toto'=>'');
foreach (keys %liste) {open TT, "<$_.txt" ; $liste{$_} = join('', <TT>)}

Mais je trouve la première solution plus jolie :), j'aimerais l'affiner
:)


C'est la solution la plus classique mais vous perdez le lien avec de "vraies"
variables.

Ceci étant, il arrive que les noms de variables proviennent d'ailleurs et
qu'on ne puisse pas faire autrement (si le code utilisant ces variables n'est
pas sous votre contrôle). Dans ce cas, je ferais comme cela :

# je suppose que $titi, $tata et $toto sont déjà déclarées...
my %liste = ('titi.txt' => $titi,
'tata.txt' => $tata,
'toto.txt' => $toto);
foreach my $filevar (keys %liste) {
undef $/; # "slurp" mode
open my $fh, "<", "$filevar"
or die "Can't read '$filevar': $!n";
${$liste{$filevar}} = <$fh>;
close $fh;
}

Cette solution fonctionne avec 'use strict;' et présente, de plus, l'avantage
de pouvoir choisir comme on le veut le nom du fichier contenant la valeur
associée à une variables.

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

Avatar
Emmanuel Florac
Le Tue, 05 Oct 2004 10:59:51 +0200, Paul Gaborit a écrit :

Cette solution fonctionne avec 'use strict;' et présente, de plus, l'avantage
de pouvoir choisir comme on le veut le nom du fichier contenant la valeur
associée à une variables.


Merci, c'est bien le genre de solution parfaitement magique que je
cherchais :)

--
Toutes les organisations ont leur règles, et les Femmes Algériennes
doivent avoir aussi leurs règles.
Kaid Ahmed.

Avatar
Jérémy JUST
On Tue, 05 Oct 2004 10:47:23 +0200
Emmanuel Florac wrote:

En fait dans ce cas précis ce qui m'amuserait ce serait de nommer
dynamiquement les variables, plutôt :) Dans ce cas aussi tu trouves
plus "perlien" de faire un bête hash?


Oui, oui.
Le hash est une structure de données magique, qui permet de faire
plein de choses de façon simple et élégante. Le principal usage
correspond exactement à ce que tu veux faire: avoir autant
d'emplacements que tu veux, retrouvables par une chaîne de caractères.

--
Jérémy JUST