Discussion:
use Switch + __DATA__ = bye bye
(trop ancien pour répondre)
luc2
2011-09-06 09:02:37 UTC
Permalink
#!/usr/bin/perl

# bonjour a tous, le script suivant n'affichera rien
# pouvez-vous m'expliquer pourquoi ?

use Switch;

while( my $l = <DATA> )
{
print $l;
}

__DATA__
1
2
3
4
5
Jean-Louis Morel
2011-09-06 10:50:40 UTC
Permalink
Post by luc2
#!/usr/bin/perl
# bonjour a tous, le script suivant n'affichera rien
# pouvez-vous m'expliquer pourquoi ?
use Switch;
while( my $l =<DATA> )
{
print $l;
}
__DATA__
1
2
3
4
5
Le module Switch surcharge '__' (voir la doc).
Pour éviter ça, utiliser :

use Switch 'noimport';

(ce n'est pas dans la doc mais dans le code du module :-) )

HTH

J-L
--
http://www.bribes.org/perl/
luc2
2011-09-06 12:18:29 UTC
Permalink
merci mon pote.
Emmanuel Florac
2011-09-06 20:11:25 UTC
Permalink
Post by luc2
use Switch;
Une remarque, pourquoi utiliser switch? son usage est déconseillé, car
dangereux et fragile, et à partir de perl 5.10 (qui est dispo même sur
les distros les plus conservatrices genre RedHat) il y a given/when qui
lui est sûr, sans danger et sans effets de bords merdiques.

tl,dr; ne pas utiliser switch, mais given/when.
--
Most software today is very much like an Egyptian pyramid with millions
of bricks piled on top of each other, with no structural integrity, but
just done by brute force and thousands of slaves.
Alan Kay
luc2
2011-09-07 07:57:02 UTC
Permalink
merci pour vos conseils
Klaus
2011-11-01 13:47:36 UTC
Permalink
Post by Emmanuel Florac
Post by luc2
use Switch;
Une remarque, pourquoi utiliser switch? son usage est déconseillé, car
dangereux et fragile, et à partir de perl 5.10 (qui est dispo même sur
les distros les plus conservatrices genre RedHat) il y a given/when qui
lui est sûr, sans danger et sans effets de bords merdiques.
tl,dr; ne pas utiliser switch, mais given/when.
given/when n'est pas non plus sans problèmes.

Voici un cas de test:

use strict;
use warnings;
use 5.010;
use Test::More tests => 2;
for my $thing ('3', ' 3') {
my $test = sprintf '%d', $thing;
my $result = '';
given ($thing) {
when ('3') { $result .= "[3]"; continue; }
when (' 3') { $result .= "[ 3]"; continue; }
}
is ($result, "[$thing]", "Test [$thing]");

}

le test échoue car le smart match entre '3' et ' 3' est positif (il
devrait être négatif car '3' ne ' 3').
Emmanuel Florac
2011-11-01 14:23:31 UTC
Permalink
Post by Klaus
le test échoue car le smart match entre '3' et ' 3' est positif (il
devrait être négatif car '3' ne ' 3').
Non, il doit être positif parce que c'est un smart match ~~, pas un
simple match eq ou ne. Vu que " 3" =~ "3", il n'y a pas d'erreur. C'est
plutôt parce que tu ne sais pas utiliser les regexp :)

Tu peux vérifier :

perl -e "print qq(match\n) if ( ' 3' =~ '3' )"
--
I love deadlines, I love the whooshing noise they make as they go by.
Douglas Adams
Klaus
2011-11-01 15:18:27 UTC
Permalink
Post by Emmanuel Florac
Post by Klaus
le test échoue car le smart match entre '3' et ' 3' est positif (il
devrait être négatif car '3' ne ' 3').
Non, il doit être positif parce que c'est un smart match ~~, pas un
simple match eq ou ne. Vu que " 3" =~ "3", il n'y a pas d'erreur. C'est
plutôt parce que tu ne sais pas utiliser les regexp :)
perl -e "print qq(match\n) if ( ' 3' =~ '3' )"
En ce qui concerne les expression régulières, tu aurais raison si
j'avais utilisé ' 3' ~~ qr{3}. Dans ce cas le smart-match utilise les
expressions régulières.

Par contre, j'ai utilisé ' 3' ~~ '3' ce qui traduit dans le cas 32.
"Any Any" ==> string equality $a eq $b du tableau
http://perldoc.perl.org/perlsyn.html#Smart-matching-in-detail
Post by Emmanuel Florac
1. $a $b Type of Match Implied Matching Code
2. ====== ===== ===================== =============
3. Any undef undefined !defined $a
4.
5. Any Object invokes ~~ overloading on $object, or dies
6.
7. Hash CodeRef sub truth for each key[1] !grep { !$b->($_) } keys %$a
9. Any CodeRef scalar sub truth $b->($a)
10.
11. Hash Hash hash keys identical (every key is found in both hashes)
13. Regex Hash hash key grep grep /$a/, keys %$b
14. undef Hash always false (undef can't be a key)
15. Any Hash hash entry existence exists $b->{$a}
16.
18. Array Array arrays are comparable[2]
21. Any Array match against an array element[3]
23.
24. Hash Regex hash key grep grep /$b/, keys %$a
26. Any Regex pattern match $a =~ /$b/
27.
29. Any Num numeric equality $a == $b
30. Num numish[4] numeric equality $a == $b
31. undef Any undefined !defined($b)
32. Any Any string equality $a eq $b
33.
34. 1 - empty hashes or arrays will match.
35. 2 - that is, each element smart-matches the element of same index in the
36. other array. [3]
37. 3 - If a circular reference is found, we fall back to referential equality.
38. 4 - either a real number, or a string that looks like a number
Emmanuel Florac
2011-11-01 16:32:20 UTC
Permalink
Par contre, j'ai utilisé ' 3' ~~ '3' ce qui traduit dans le cas 32. "Any
Any" ==> string equality $a eq $b du tableau
http://perldoc.perl.org/perlsyn.html#Smart-matching-in-detail
Dans ce cas ça doit être un bug de smart match, puisque ça ne correspond
pas à ce qu'on obtient ( ' a' ~~ 'a', en l'occurence c'est facile à
vérifier).
--
Ce qu'il y a d'enivrant dans le mauvais goût c'est le plaisir
aristocratique de déplaire.
C. Baudelaire.
Klaus
2011-11-01 17:38:16 UTC
Permalink
Post by Emmanuel Florac
Par contre, j'ai utilisé ' 3' ~~ '3' ce qui traduit dans le cas 32. "Any
Any" ==> string equality $a eq $b du tableau
http://perldoc.perl.org/perlsyn.html#Smart-matching-in-detail
Dans ce cas ça doit être un bug de smart match, puisque ça ne correspond
pas à ce qu'on obtient ( ' a' ~~ 'a', en l'occurence c'est facile à
vérifier).
Pour être précis, les cas ' 3' ~~ '3' est positif uniquement parce que
la chaîne de caractères ' 3' a été utilisé dans un printf ("...my
$test = sprintf '%d', $thing;..."). Je précise bien que la chaîne de
caractères ' 3' reste une chaîne de caractères ' 3'.

use strict;
use warnings;
use 5.010;
use Test::More tests => 2;
for my $thing ('3', ' 3') {
my $test = sprintf '%d', $thing;
my $result = '';
given ($thing) {
when ('3') { $result .= "[3]"; continue; }
when (' 3') { $result .= "[ 3]"; continue; }
}
is ($result, "[$thing]", "Test [$thing]");
}

Je souhaite juste rajouter que le bug ' 3' ~~ '3' est documenté dans
http://perldoc.perl.org/perlsyn.html#Smart-matching-in-detail
Post by Emmanuel Florac
30. Num numish[4] numeric equality $a == $b
C'est à dire le sprintf a provoqué que la chaîne de caractères ' 3'
est considéré comme numérique, donc règle 30. devient active et
provoque une comparaison ' 3' == '3'.

A mon avis, le vrai bug est la règle 30. Si cette règle n'existait
pas, le problème ' 3' ~~ '3' serait résolu.
Emmanuel Florac
2011-11-01 18:07:42 UTC
Permalink
A mon avis, le vrai bug est la règle 30. Si cette règle n'existait pas,
le problème ' 3' ~~ '3' serait résolu.
Allons plus loin, le smart match est un problème dans beaucoup de cas, ce
n'est jamais très clair. Je pense que c'est bien le smart match qui est
une fonctionnalité complètement ratée, pas vraiment le given/when.
--
"If you're not paying for it, you're not the customer; you are
the product being sold."
Marc Espie
2011-11-01 14:35:33 UTC
Permalink
Le blog de chromatics dit d'ailleurs que finalement, given...when risque
plus d'etre une experience temporaire qu'une fonctionnalite qui va rester...
au contraire d'autres bouts plus triviaux comme say...
Klaus
2011-11-01 15:30:12 UTC
Permalink
Le blog de chromatics  dit d'ailleurs que finalement, given...when risque
plus d'etre une experience temporaire qu'une fonctionnalite qui va rester...
au contraire d'autres bouts plus triviaux comme say...
Actuellement, il y a un développement en cours (Perl 5.14 / Perl 5.15)
qui essaie de corriger les problèmes de given/when par un nouveau
module:
voir https://groups.google.com/group/perl.perl5.porters/msg/c869d4e8b7fe5d88?hl=fr
I'd argue that yes, there is some progress. Jesse Luehrs did an initial
pass at extracting smartmatch into a module and then implementing a
"less-smart" smartmatch designed by rjbs that could be swapped out
lexically.
[...]
https://github.com/doy/smartmatch
https://github.com/doy/smartmatch-engine-core
https://github.com/doy/smartmatch-engine-rjbs
(and there are development releases of the first two on CPAN already).
Emmanuel Florac
2011-11-01 16:30:53 UTC
Permalink
Post by Klaus
Actuellement, il y a un développement en cours (Perl 5.14 / Perl 5.15)
qui essaie de corriger les problèmes de given/when par un nouveau
voir
https://groups.google.com/group/perl.perl5.porters/msg/c869d4e8b7fe5d88?
hl=fr

De ce que j'en comprends c'est plutôt le smart match qui pose problème.
--
Le commissaire : Comment vous appelez-vous?
Garance : Moi je ne m'appelle jamais, je suis toujours là. J'ai pas
besoin de m'appeler. Mais les autres m'appellent Garance, si ça peut
vous intéresser.
Prévert,"les enfants du Paradis".
Klaus
2011-11-01 17:03:16 UTC
Permalink
Post by Emmanuel Florac
Post by Klaus
Actuellement, il y a un développement en cours (Perl 5.14 / Perl 5.15)
qui essaie de corriger les problèmes de given/when par un nouveau
voir
https://groups.google.com/group/perl.perl5.porters/msg/c869d4e8b7fe5d88?
hl=fr
De ce que j'en comprends c'est plutôt le smart match qui pose problème.
Dans mon cas, oui, c'est le smart match qui pose le problème. Mais il
y a beaucoup de problèmes supplémentaires qui touchent le smart match
et la fonctionnalité given/when en même temps, par exemple:
https://groups.google.com/group/perl.perl5.porters/msg/b529f00b0566466b?hl=fr
Post by Emmanuel Florac
.
| when($foo)
| is exactly equivalent to
| when($_ ~~ $foo)
| Most of the time, "when(EXPR)" is treated as an implicit
| smart match of $_, i.e. "$_ ~~ EXPR".
.
Those cannot both be true. And they are not. The first is lying.
The second is insufficient, even with elaboration, to explain what
is really going on.
Donc il est raisonnable de traiter les problèmes given/when et les
problèmes de smart match en même temps.
Loading...