eval + return = fin du monde

Le
luc2
#!/usr/bin/perl

use strict;

# bonjour, je pensais empecher la fin du monde en utilisant "return",
# mais j'ai echoue. je comprends a peu pres le pourquoi du comment,
# mais j'ai pas apprecie le piege

sub fin_du_monde
{
eval
{
return "je quitte la fonction pour eviter la fin du monde";
};

return "destruction de l'univers";
}

print fin_du_monde;
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Paul Gaborit
Le #23760141
À (at) 14 Sep 2011 13:06:41 GMT,
luc2
#!/usr/bin/perl

use strict;

# bonjour, je pensais empecher la fin du monde en utilisant "return",
# mais j'ai echoue. je comprends a peu pres le pourquoi du comment,
# mais j'ai pas apprecie le piege...

sub fin_du_monde
{
eval
{
return "je quitte la fonction pour eviter la fin du monden";
};

return "destruction de l'universn";
}

print fin_du_monde;



Ce n'est pas un piège et c'est documenté (dans perlfunc à la section
'eval'). Un 'return' au plus haut niveau du contenu d'un 'eval' (que ce
soit un bloc comme dans votre cas ou une chaîne) définit le résultat du
'eval'.

Le bout de code suivant :

$a = eval {return 42};
print "$an";

affichera 42.

--
Paul Gaborit - Perl en français -
gerbier
Le #23760461
Le 14/09/2011 15:06, luc2 a écrit :
#!/usr/bin/perl

use strict;

# bonjour, je pensais empecher la fin du monde en utilisant "return",
# mais j'ai echoue. je comprends a peu pres le pourquoi du comment,
# mais j'ai pas apprecie le piege...

sub fin_du_monde
{
eval
{
return "je quitte la fonction pour eviter la fin du monden";
};

return "destruction de l'universn";
}

print fin_du_monde;



il suffit de changer peu de choses : un return en die et un test

#!/usr/bin/perl

use strict;

# bonjour, je pensais empecher la fin du monde en utilisant "return",
# mais j'ai echoue. je comprends a peu pres le pourquoi du comment,
# mais j'ai pas apprecie le piege...

sub fin_du_monde
{
eval
{
die "Argh ....n";
};
if ($@) {
return "je quitte la fonction pour eviter la fin du monden";
}

return "destruction de l'universn";
}

print fin_du_monde;
luc2
Le #23760291
si. c'est un piege. ca peut preter a confusion, donc, c'est un piege.

le fait que ce soit documente, explicable ou comprehensible n'empeche pas que
ce soit un piege.

c'est comme les faux-amis entre 2 langues differentes : c'est documente,
explicable et comprehensible, et pourtant, ce sont des pieges.
espie
Le #23760341
In article luc2
si. c'est un piege. ca peut preter a confusion, donc, c'est un piege.

le fait que ce soit documente, explicable ou comprehensible n'empeche pas que
ce soit un piege.

c'est comme les faux-amis entre 2 langues differentes : c'est documente,
explicable et comprehensible, et pourtant, ce sont des pieges.




Bof, bof, bof.

C'est perl, hein. entre last, next, return, eval, die, ca offre pas mal
de possibilites de confusions semantiques (le fonctionnement d'eval/die/$@
est suffisamment complexe pour avoir suscite "quelques" modifications dans les
perl recents, par exemple).

Si c'est un "piege" pour toi, tu n'es pas au bout de tes amusements.
Paul Gaborit
Le #23760561
À (at) 14 Sep 2011 14:59:34 GMT,
luc2
si. c'est un piege. ca peut preter a confusion, donc, c'est un piege.



Ça ne prête à confusion que pour ceux qui ont des idées préconçues sur
le fonctionnement de 'return' et de 'eval'.

le fait que ce soit documente, explicable ou comprehensible n'empeche pas que
ce soit un piege.



Vu l'endroit où c'est documenté (à la fois dans 'eval' et dans
'return'), le fait de dire que c'est un piège est en fait un jugement de
valeur (sur celui qui tombe dedans).

Il existe de vrais pièges en Perl (commme dans tous les autres langages)
qui, eux, sont mal ou pas documentés du tout. Par exemple, le piège des
fuites mémoires liées aux références circulaires n'est qu'évoqué dans
perlref avec un renvoi vers perlobj qui l'explique un peu mieux mais ne
fournit pas de solution. Ça, c'est un vrai piège du langage difficile à
comprendre et difficile à résoudre.

--
Paul Gaborit - Perl en français -
espie
Le #23760631
In article Paul Gaborit
Il existe de vrais pièges en Perl (commme dans tous les autres langages)
qui, eux, sont mal ou pas documentés du tout. Par exemple, le piège des
fuites mémoires liées aux références circulaires n'est qu'évoqué dans
perlref avec un renvoi vers perlobj qui l'explique un peu mieux mais ne
fournit pas de solution. Ça, c'est un vrai piège du langage difficile à
comprendre et difficile à résoudre.



Dans le meme genre, le gc n'en sort assez mal avec les variables locales
capturees par des sub anonymes. Par exemple, penser a fermer explicitement
les fichiers dans les lambda, sous peine de se retrouver avec trop de
fichiers ouverts...
luc2
Le #23762801
Le 14-09-2011, Paul Gaborit
si. c'est un piege. ca peut preter a confusion, donc, c'est un piege.



Ça ne prête à confusion que pour ceux qui ont des idées préconçues sur
le fonctionnement de 'return' et de 'eval'.



une grosse majorite quoi...

le fait que ce soit documente, explicable ou comprehensible n'empeche pas que
ce soit un piege.



Vu l'endroit où c'est documenté...



mon affirmation tenait deja compte de l'endroit.

...(à la fois dans 'eval' et dans 'return'), le fait de dire que c'est un
piège est en fait un jugement de valeur (sur celui qui tombe dedans).



'pas besoin de determiner s'il s'agit d'un jugement de valeur ou pas, meme sans
jugement de valeur, on peut toujours deformer la verite.

Il existe de vrais pièges en Perl (commme dans tous les autres langages)
qui, eux, sont mal ou pas documentés du tout. Par exemple, le piège des
fuites mémoires liées aux références circulaires n'est qu'évoqué dans
perlref avec un renvoi vers perlobj qui l'explique un peu mieux mais ne
fournit pas de solution. Ça, c'est un vrai piège du langage difficile à
comprendre et difficile à résoudre.



ce n'est pas parce qu'il existe des pieges plus vicieux que celui-ci n'en est
pas un.
Paul Gaborit
Le #23763191
À (at) Wed, 14 Sep 2011 18:33:16 +0200,
Tower

Le 14/09/2011 18:03, Paul Gaborit a écrit :
Il existe de vrais pièges en Perl (commme dans tous les autres langages)
qui, eux, sont mal ou pas documentés du tout. Par exemple, le piège des
fuites mémoires liées aux références circulaires n'est qu'évoqué dans
perlref avec un renvoi vers perlobj qui l'explique un peu mieux mais ne
fournit pas de solution. Ça, c'est un vrai piège du langage difficile à
comprendre et difficile à résoudre.



Je vous serais reconnaissant de bien vouloir poster un petit bout de
code pour montrer exactement ce à quoi vous faites allusion.




Un exemple tout simple :

{
my $pere = {};
$pere->{fils} = {pere => $pere};
}

Normalement, cette structure de données devraient étre détruite à la fin
du bloc... Mais elle ne l'est pas à cause des références circulaires (le
père référence son fils qui référence son père...). C'est donc une fuite
mémoire.

Le module Devel::Cycle propose la fonction find_cycle pour détecter ce
type de soucis. Pour s'en sortir soit on casse soi-même les références
circulaires avant la fin du bloc (en faisant par exemple 'undef
$pere->{fils}') soit on utilise des références faibles en utilisant la
fonction 'weaken' proposée par le module Scalar::Util. Pour l'exemple
ci-dessus, cela donnerait :

{
my $pere = {};
$pere->{fils} = {pere => $pere};
weaken($pere->{fils}{pere});
}




--
Paul Gaborit - Perl en français -
Erwan David
Le #23763471
Paul Gaborit
À (at) Wed, 14 Sep 2011 18:33:16 +0200,
Tower

Le 14/09/2011 18:03, Paul Gaborit a écrit :
Il existe de vrais pièges en Perl (commme dans tous les autres langages)
qui, eux, sont mal ou pas documentés du tout. Par exemple, le piège des
fuites mémoires liées aux références circulaires n'est qu'évoqué dans
perlref avec un renvoi vers perlobj qui l'explique un peu mieux mais ne
fournit pas de solution. Ça, c'est un vrai piège du langage difficile à
comprendre et difficile à résoudre.



Je vous serais reconnaissant de bien vouloir poster un petit bout de
code pour montrer exactement ce à quoi vous faites allusion.




Un exemple tout simple :

{
my $pere = {};
$pere->{fils} = {pere => $pere};
}

Normalement, cette structure de données devraient étre détruite à la fin
du bloc... Mais elle ne l'est pas à cause des références circulaires (le
père référence son fils qui référence son père...). C'est donc une fuite
mémoire.



tu veux dire que le GC de perl est un simple compteur de références ?
Ça faut quand même des années qu'on sait faire mieux...


--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Alain Ketterlin
Le #23763541
Erwan David
Paul Gaborit
Un exemple tout simple :

{
my $pere = {};
$pere->{fils} = {pere => $pere};
}

Normalement, cette structure de données devraient étre dé truite à la fin
du bloc... Mais elle ne l'est pas à cause des références circulaires (le
père référence son fils qui référence son pà ¨re...). C'est donc une fuite
mémoire.



tu veux dire que le GC de perl est un simple compteur de référe nces ?
Ça faut quand même des années qu'on sait faire mieux...



Je partage ta stupéfaction, et en allant lire les documents auquel Paul
faisait référence, j'ai bien peur que ce soit le cas...

-- Alain.
Publicité
Poster une réponse
Anonyme