NOM |
perltrap - Les pièges de Perl pour l'imprudent
Le plus grand des pièges est d'oublier d'utiliser l'option -w ;
voir the perlrun manpage. Le deuxième plus grand piège est de ne pas rendre la
totalité de votre programme exécutable sous use strict
. Le
troisième plus grand piège est de ne pas lire la liste des changements
effectués dans cette version de Perl ; voir the perldelta manpage.
Les utilisateurs avertis de awk devraient se soucier particulièrement de ce qui suit :
use English;
vous permet de vous référer aux variables spéciales (comme $/
) par
des noms (comme $RS), comme si elles étaient en awk ; voir
the perlvar manpage pour plus de détails.
if
s et les while
s.
substr()
et index()
dans les chaînes sont
comptées à partir de 0.
split()
a des
arguments différents qu'en awk.
print()
n'ajoute pas de séparateurs de champs et
d'enregistrements à moins que vous ne fixiez $,
et $\
. Vous
pouvez fixer $OFS et $ORS si vous utilisez le module English.
/pat/ /pat/
impossible à analyser
lexicalement, car le troisième signe de division serait interprété
comme un opérateur de division -- le détecteur de mots-clés est en
fait légèrement sensible au contexte pour les opérateurs tels que ``/'',
``?'', et ``>''. Et en fait, ``.'' lui-même peut être le début d'un nombre).
next
, exit
, et continue
fonctionnement
différemment.
Awk Perl ARGC $#ARGV ou @ARGV scalaire ARGV[0] $0 FILENAME $ARGV FNR $. - quelque chose FS (ce que vous voulez) NF $#Fld, ou quelque chose comme ça NR $. OFMT $# OFS $, ORS $\ RLENGTH length($&) RS $/ RSTART length($`) SUBSEP $;
Les programmes C cérébraux devraient prendre note de ce qui suit :
if
s et les while
s.
elsif
à la place de else if
.
break
et continue
de C deviennent respectivement
last
et next
en Perl. Contrairement au C, ceux-ci ne
fonctionnent pas à l'intérieur d'une structure do { } while
.
printf()
n'implémente pas le format ``*'' interpolant les largeurs de
champs, mais il est trivial d'utiliser l'interpolation de chaînes
entre guillemets pour obtenir le même résultat.
ARGV
doit être en majuscules. $ARGV[0]
est l'argv[1]
du C, et
argv[0]
atterrit dans $0
.
kill -l
pour déterminer leurs noms sur votre
système.
Les programmeurs sed expérimentés devraient prendre note de ce qui suit :
...
, à la place de la virgule.
les programmeurs shell dégourdis devraient prendre note de ce qui suit :
BEGIN
, qu'il exécute lors de la compilation).
Les programmeurs Perl pratiquants devraient prendre note de ce qui suit :
chop()
et
chdir())
de celles qui sont des opérateurs de liste (comme print()
et
unlink()). (Les sous-programmes définis par l'utilisateur ne peuvent
être que des opérateurs de liste, jamais des opérateurs
unaires). Voir the perlop manpage.
while (<FH>) { } while (defined($_ = <FH>)) { }.. <FH>; # données rejetées !
=
lorsque vous avez besoin de
=~
; ces deux structures sont très différentes :
$x = /foo/; $x =~ /foo/;
do {}
n'est pas une vraie boucle sur laquelle vous
pouvez utiliser un contrôle de boucle (? NDT).
my()
pour les variables locales chaque fois que vous
pouvez vous en satisfaire (mais voyez the perlform manpage pour les cas où vous
ne le pouvez pas). L'utilisation de local()
donne vraiment une
valeur locale à une variable globale, ce qui vous met à la merci
d'effets secondaires de portée dynamique imprévus.
Les programmeurs Perl4 pratiquants devraient prendre note des pièges suivants, spécifiques au passage entre Perl4 et Perl5.
Ils sont crûment commandés par la liste suivante :
dbmopen()
, et aux
implémentations particulières de dbm.
Si vous trouvez un exemple de piège de conversion qui ne soit pas
listé ici, soumettez-le à Bill Middleton <wjm@best.com> en vue de
son inclusion. Notez aussi qu'au moins certains de ceux qui suivent
peuvent être capturés par le pragma use warnings
ou par l'option
-w.
Tout ce qui a été abandonné, désapprouvé ou corrigé comme étant un bug depuis perl4.
$_
lui-même (ainsi que @_
, etc.).
package test; $_legacy = 1;
package main; print "\$_legacy is ",$_legacy,"\n";
# perl4 affiche : $_legacy is 1 # perl5 affiche : $_legacy is
$a=1;$b=2;$c=3;$var=4; print "$a::$b::$c "; print "$var::abc::xyz\n";
# perl4 affiche : 1::2::3 4::abc::xyz # perl5 affiche : 3
Étant donné que ::
est maintenant le délimiteur de paquetage
préféré, on peut se demander si ceci doit être considéré comme un bug
ou non (l'ancien délimiteur de paquetage, ' , est utilisé ici).
$x = 10 ; print "x=${'x}\n" ;
# perl4 affiche : x=10 # perl5 affiche : Can't find string terminator "'" anywhere before EOF
Vous pouvez éviter ce problème, en restant compatible avec perl4, si vous incluez toujours explicitement le nom du paquetage :
$x = 10 ; print "x=${main'x}\n" ;
Voyez aussi les pièges de précédence, pour l'analyse de $:
.
splice()
sont désormais
évalués dans un contexte scalaire (comme l'indique le Camel) plutôt
que dans un contexte de liste.
sub sub1{return(0,2) } # retourne une liste de 2 éléments sub sub2{ return(1,2,3)} # retourne une liste de 3 éléments @a1 = ("a","b","c","d","e"); @a2 = splice(@a1,&sub1,&sub2); print join(' ',@a2),"\n";
# perl4 affiche : a b # perl5 affiche : c d e
goto
dans un bloc optimisé. Mince.
goto marker1;
for(1){ marker1: print "Here I is!\n"; }
# perl4 affiche : Here I is! # perl5 effectue un vidage mémoire (SEGV)
$a = ("foo bar"); $b = q baz ; print "a is $a, b is $b\n";
# perl4 affiche : a is foo bar, b is baz # erreur de perl5 : Bareword found where operator expected
if { 1 } { print "True!"; } else { print "False!"; }
# perl4 affiche : True! # erreur de perl5 : syntax error at test.pl line 1, near "if {"
**
se lie désormais plus étroitement que le moins
unaire. Cela devait fonctionner ainsi selon la documentation, mais ce
n'était pas le cas.
print -4**2,"\n";
# perl4 affiche : 16 # perl5 affiche : -16
foreach{}
a légèrement changé lorsqu'il
traverse une liste qui n'est pas un tableau. C'était utilisé pour
affecter la liste à un tableau temporaire, mais ce n'est plus le cas
(pour des raisons d'efficacité). Cela veut dire que vous devrez
désormais itérer sur les vraies valeurs, pas sur des copies de ces
valeurs. Les modifications de la variable de boucle peuvent changer
les valeurs originelles.
@list = ('ab','abc','bcd','def'); foreach $var (grep(/ab/,@list)){ $var = 1; } print (join(':',@list));
# perl4 affiche : ab:abc:bcd:def # perl5 affiche : 1:1:bcd:def
Pour garder la sémantique de Perl4, vous devrez affecter explicitement votre liste à un tableau temporaire puis itérer dessus. Vous pourriez par exemple devoir changer
foreach $var (grep(/ab/,@list)){
en
foreach $var (@tmp = grep(/ab/,@list)){
Sinon changer $var modifiera les valeurs de @list (Cela arrive le plus
souvent lorsque vous utilisez $_
comme variable de boucle, et
appelez dans celle-ci des sous-programmes qui ne localisent pas
correctement $_
).
split
sans argument se comporte désormais comme split ' '
(qui
ne retourne pas de champ nul initial si $_ commence par une espace),
il se comportait habituellement comme split /\s+/
(qui le fait).
$_ = ' hi mom'; print join(':', split);
# perl4 affiche : :hi:mom # perl5 affiche : hi:mom
perl -e'print "attached to -e"' 'print "separate arg"'
# perl4 affiche : separate arg # perl5 affiche : attached to -e
perl -e
# perl4 affiche : # perl5 meurt : No code specified for -e.
push
n'était pas documentée, mais
c'était en fait la dernière valeur poussée sur la liste cible. En Perl
5, la valeur de retour de push
est documentée, mais elle a changé,
c'est désormais le nombre d'éléments de la liste résultante.
@x = ('existing'); print push(@x, 'first new', 'second new');
# perl4 affiche : second new # perl5 affiche : 3
Pièges entre Perl4 et Perl5 ayant un rapport avec l'analyse syntaxique.
$string . = "more string"; print $string;
# perl4 affiche: more string # perl5 affiche : syntax error at - line 1, near ". ="
sub foo {} &foo print("hello, world\n");
# perl4 affiche : hello, world # perl5 affiche : syntax error
print ($foo == 1) ? "is one\n" : "is zero\n";
# perl4 affiche : is zero # perl5 avertit : "Useless use of a constant in void context" if using -w
$#array
diffère lorsque
des accolades sont utilisées autour du nom.
@ = (1..3); print "${#a}";
# perl4 affiche : 2 # perl5 échoue sur une erreur de syntaxe
@ = (1..3); print "$#{a}";
# perl4 affiche : {a} # perl5 affiche : 2
Pièges entre Perl4 et Perl5 ayant un rapport avec les opérateurs numériques, les opérandes, ou leurs sorties.
print 7.373504 - 0, "\n"; printf "%20.18f\n", 7.373504 - 0;
# Perl4 affiche : 7.375039999999996141 7.37503999999999614
# Perl5 affiche : 7.373504 7.37503999999999614
use Math::BigInt;
$p = ($test == 1); print $p,"\n";
# perl4 affiche : 0 # perl5 affiche :
Voir aussi Pièges des Expressions Rationnelles Générales lors de l'utilisation de s///, etc. pour un autre exemple de cette nouvelle caractéristique...
& | ^ ~
) n'ont que des chaînes pour
arguments, perl4 traite les opérandes comme des chaînes de bits dans
la mesure où le programme contenait un appel à la fonction
vec()
. perl5 traite les opérandes chaînes comme des chaînes de bits
(Voir Opérateurs bit à bit sur les chaînes in the perlop manpage pour plus de
détails).
$fred = "10"; $barney = "12"; $betty = $fred & $barney; print "$betty\n"; # Décommentez la ligne suivante pour changer le comportement de perl4 # ($dummy) = vec("dummy", 0, 0);
# Perl4 affiche : 8
# Perl5 affiche : 10
# Si vec() est utilisé quelque part dans le programme, les deux # affichent : 10
Pièges entre Perl4 et Perl5 impliquant la plupart des types de données, et leur usage dans certaines expressions et/ou contextes.
@a = (1, 2, 3, 4, 5); print "The third element of the array is $a[3] also expressed as $a[-2] \n";
# perl4 affiche : The third element of the array is 4 also expressed as # perl5 affiche : The third element of the array is 4 also expressed as 4
$#array
supprime désormais des éléments du
tableau, et rend impossible leur récupération.
@a = (a,b,c,d,e); print "Before: ",join('',@a); $#a =1; print ", After: ",join('',@a); $#a =3; print ", Recovered: ",join('',@a),"\n";
# perl4 affiche : Before: abcde, After: ab, Recovered: abcd # perl5 affiche : Before: abcde, After: ab, Recovered: ab
local($s,@a,%h); die "scalar \$s defined" if defined($s); die "array \@a defined" if defined(@a); die "hash \%h defined" if defined(%h);
# perl4 affiche : # perl5 meurt : hash %h defined
Perl génère désormais un avertissement lorsqu'il voit defined(@a)
et
defined(%h).
@a = ("This is Perl 4"); *b = *a; local(@a); print @b,"\n";
# perl4 affiche : This is Perl 4 # perl5 affiche :
undef
à un glob n'a pas d'effet en Perl 5. En Perl
4, elle indéfinit le scalaire associé (mais peut avoir d'autres effets
de bord, y compris des SEGVs).
$x = "aaa"; print ++$x," : "; print -$x," : "; print ++$x,"\n";
# perl4 affiche : aab : -0 : 1 # perl5 affiche : aab : -aab : aac
$foo = "x"; &mod($foo); for ($x = 0; $x < 3; $x++) { &mod("a"); } sub mod { print "before: $_[0]"; $_[0] = "m"; print " after: $_[0]\n"; }
# perl4: # before: x after: m # before: a after: m # before: m after: m # before: m after: m
# Perl5: # before: x after: m # Modification of a read-only value attempted at foo.pl line 12. # before: a
print "$x", defined $x
# perl 4: 1 # perl 5: <no output, $x is not called into existence>
$aGlobal{ "aKey" } = "global value"; print "MAIN:", $aGlobal{"aKey"}, "\n"; $GlobalLevel = 0; &test( *aGlobal );
sub test { local( *theArgument ) = @_; local( %aNewLocal ); # perl 4 != 5.001l,m $aNewLocal{"aKey"} = "this should never appear"; print "SUB: ", $theArgument{"aKey"}, "\n"; $aNewLocal{"aKey"} = "level $GlobalLevel"; # what should print $GlobalLevel++; if( $GlobalLevel<4 ) { &test( *aNewLocal ); } }
# Perl4: # MAIN:global value # SUB: global value # SUB: level 0 # SUB: level 1 # SUB: level 2
# Perl5: # MAIN:global value # SUB: global value # SUB: this should never appear # SUB: this should never appear # SUB: this should never appear
@fmt = ("foo","bar","baz"); format STDOUT= @<<<<< @||||| @>>>>> @fmt; . write;
# erreur de perl4 : Please use commas to separate fields in file # perl5 affiche : foo bar baz
caller()
retourne maintenant la valeur faux dans un
contexte scalaire s'il n'y a pas d'appelant. Cela laisse les fichiers
de bibliothèque déterminer s'ils sont en train d'être demandés.
caller() ? (print "You rang?\n") : (print "Got a 0\n");
# erreur de perl4 : There is no caller # perl5 affiche : Got a 0
@y= ('a','b','c'); $x = (1, 2, @y); print "x = $x\n";
# Perl4 affiche : x = c # pense contexte de liste, # interpole la liste # Perl5 affiche : x = 3 # sait que le scalaire utilise la # longueur de la liste
sprintf()
(argument tableau converti en nombre
scalaire d'éléments du tableau) Ce test pourrait être ajouté à
t/op/sprintf.t
@z = ('%s%s', 'foo', 'bar'); $x = sprintf(@z); if ($x eq 'foobar') {print "ok 2\n";} else {print "not ok 2 '$x'\n";}
# perl4 affiche : ok 2 # perl5 affiche : not ok 2
printf()
fonctionne toutefois bien :
printf STDOUT (@z); print "\n";
# perl4 affiche : foobar # perl5 affiche : foobar
Probablement un bug.
Pièges entre Perl4 et Perl5 impliquant l'ordre de précédence.
Perl 4 a presque les mêmes règles de précédence que Perl 5 pour les opérateurs qu'ils ont en commun. Toutefois, Perl 4 semble avoir contenu des incohérences ayant rendu son comportement différent de celui qui était documenté.
@arr = ( 'left', 'right' ); $a{shift @arr} = shift @arr; print join( ' ', keys %a );
# perl4 affiche : left # perl5 affiche : right
@list = (1,2,3,4,5); %map = ("a",1,"b",2,"c",3,"d",4); $n = shift @list + 2; # premier élément de la liste plus 2 print "n is $n, "; $m = keys %map + 2; # nombre d'éléments du hachage plus 2 print "m is $m\n";
# perl4 affiche : n is 3, m is 6 # erreur de perl5 et échec de la compilation
/foo/ ? ($a += 2) : ($a -= 2);
Autrement
/foo/ ? $a += 2 : $a -= 2
serait analysé de façon erronée sous la forme
(/foo/ ? $a += 2 : $a) -= 2;
D'autre part,
$a += /foo/ ? 1 : 2;
fonctionne désormais comme un programmeur C pourrait s'y attendre.
open FOO || die;
est désormais incorrect. Vous devez mettre le handle de fichier entre parenthèses. Sinon, perl5 laisse sa précédence par défaut à l'instruction :
open(FOO || die);
# perl4 ouvre ou meurt # erreur de perl5 : Precedence problem: open FOO should be open(FOO)
$:
, tandis que
perl5 traite $::
comme étant le paquetage
principale
$a = "x"; print "$::a";
# perl 4 affiche : -:a # perl 5 affiche : x
-e $foo .= "q"
devrait être
analysé comme ((-e $foo) .= "q")
, il l'analyse en fait comme (-e
($foo .= "q"))
. En perl5, la précédence est telle que documentée.
-e $foo .= "q"
# perl4 affiche : no output # perl5 affiche : Can't modify -e in concatenation
each()
et values()
étaient des opérateurs spéciaux
de haute précédence qui agissaient sur un simple hachage, mais en
perl5, ce sont des opérateurs unaires nommés normaux. Tels que
documentés, ces opérateurs ont une précédence plus basse que les
opérateurs arithmétiques et de concaténation + - .
, mais les
variantes de perl4 de ces opérateurs se lient en fait plus étroitement
que + - .
. Ainsi, pour :
%foo = 1..10; print keys %foo - 1
# perl4 affiche : 4 # perl5 affiche : Type of arg 1 to keys must be hash (not subtraction)
Le comportement de perl4 était probablement plus utile, mais moins cohérent.
Tous types de pièges concernant les expressions rationnelles.
s'$lhs'$rhs'
n'effectue désormais d'interpolation ni d'un côté ni
de l'autre. $lhs était habituellement interpolé, mais pas $rhs (et ne
détecte toujours pas un '$' littéral dans la chaîne)
$a=1;$b=2; $string = '1 2 $a $b'; $string =~ s'$a'$b'; print $string,"\n";
# perl4 affiche : $b 2 $a $b # perl5 affiche : 1 2 $a $b
m//g
attache maintenant son état à la chaîne fouillée plutôt que
l'expression rationnelle (une fois que la portée d'un bloc est
quittée pour le sous-programme, l'état de la chaîne fouillée est
perdu)
$_ = "ababab"; while(m/ab/g){ &doit("blah"); } sub doit{local($_) = shift; print "Got $_ "}
# perl4 affiche : blah blah blah # perl5 affiche : boucle infinie de blah...
m//o
sur une
expression rationnelle dans un sous-programme anonyme, toutes les
fermetures générées dans ce sous-programme anonyme utiliseront
l'expression rationnelle telle qu'elle a été compilée lors de sa toute
première utilisation dans une telle fermeture. Par exemple, si vous
dites
sub build_match { my($left,$right) = @_; return sub { $_[0] =~ /$left stuff $right/o; }; }
build_match()
retournera toujours un sous-programme qui correspondra
au contenu de $left et de $right tels qu'ils étaient la première
fois que build_match()
a été appelé, et pas tels qu'ils sont dans
l'appel en cours.
C'est probablement un bug, et cela pourrait changer dans les futures versions de Perl.
$+
à toute la corerspondance, tout comme $&
. Perl5 ne le
fait pas.
"abcdef" =~ /b.*e/; print "\$+ = $+\n";
# perl4 affiche : bcde # perl5 affiche :
$string = "test"; $value = ($string =~ s/foo//); print $value, "\n";
# perl4 affiche : 0 # perl5 affiche :
Voir aussi Pièges Numériques pour un autre exemple de cette nouvelle caractéristique.
s`lhs`rhs`
(en utilisant des accents graves) est maintenant une
substitution normale, sans expansion des accents graves
$string = ""; $string =~ s`^`hostname`; print $string, "\n";
# perl4 affiche : <the local hostname> # perl5 affiche : hostname
s/^([^$grpc]*$grpc[$opt$plus$rep]?)//o;
# perl4: compile sans erreur # perl5: compile avec Scalar found where operator expected ..., near "$opt$plus"
un composant ajouté de cet exemple, apparemment depuis le même script,
est la véritable valeur de la chaîne fouillée après la substitution
(NDT ?). [$opt]
est une classe de caractère en perl4 et un indice
de tableau en perl5
$grpc = 'a'; $opt = 'r'; $_ = 'bar'; s/^([^$grpc]*$grpc[$opt]?)/foo/; print ;
# perl4 affiche : foo # perl5 affiche : foobar
m?x?
ne correspond qu'une fois, comme ?x?
. Sous
perl4, cela correspondait plusieurs fois, comme /x/
ou m!x!
.
$test = "once"; sub match { $test =~ m?once?; } &match(); if( &match() ) { # m?x? correspond plusieurs fois print "perl4\n"; } else { # m?x? correspond une seule fois print "perl5\n"; }
# perl4 affiche : perl4 # perl5 affiche : perl5
Le groupe général de pièges entre Perl4 et Perl5 ayant un rapport avec les Signaux, les Tris, et leurs sous-programmes associés, ainsi que les pièges généraux liés aux sous-programmes. Cela inclut certains pièges spécifiques au système d'exploitation.
sub SeeYa { warn"Hasta la vista, baby!" } $SIG{'TERM'} = SeeYa; print "SIGTERM is now $SIG{'TERM'}\n";
# perl4 affiche : SIGTERM is main'SeeYa # perl5 affiche : SIGTERM is now main::1
Utilisez -w pour capturer celui-ci
sub reverse{ print "yup "; $a <=> $b } print sort reverse a,b,c;
# perl4 affiche : yup yup yup yup abc # perl5 affiche : abc
warn()
ne vous laisse pas spécifier un handle de fichier.warn()
vous laissait
spécifier un handle de fichier en perl4. Avec perl5, ce n'est plus le
cas.
warn STDERR "Foo!";
# perl4 affiche : Foo! # perl5 affiche : String found where operator expected
Depuis la version 5.002, Perl utilise sigaction()
sous SysV.
sub gotit { print "Got @_... "; } $SIG{'INT'} = 'gotit';
$| = 1; $pid = fork; if ($pid) { kill('INT', $pid); sleep(1); kill('INT', $pid); } else { while (1) {sleep(10);} }
# perl4 (HPUX) affiche : Got INT... # perl5 (HPUX) affiche : Got INT... Got INT...
seek()
sur un
fichier ouvert en mode d'ajout >>
fait désormais ce qu'il
doit selon la page de manuel de fopen(). C'est-à-dire que lorsqu'un
fichier est ouvert en mode d'ajout, il est impossible d'écraser les
informations déjà présentes dans le fichier.
open(TEST,">>seek.test"); $start = tell TEST ; foreach(1 .. 9){ print TEST "$_ "; } $end = tell TEST ; seek(TEST,$start,0); print TEST "18 characters here";
# perl4 (solaris) seek.test dit : 18 characters here # perl5 (solaris) seek.test dit : 1 2 3 4 5 6 7 8 9 18 characters here
Pièges entre Perl4 et Perl5 ayant un rapport avec la façon dont les choses sont interpolées dans certaines expressions, instructions, dans certains contexts, ou quoi que ce soit d'autre.
print "To: someone@somewhere.com\n";
# perl4 affiche : To:someone@somewhere.com # erreur de perl5 : In string, @somewhere now must be written as \@somewhere
$foo = "foo$"; $bar = "bar@"; print "foo is $foo, bar is $bar\n";
# perl4 affiche : foo is foo$, bar is bar@ # erreur de perl5 : Final $ should be \$ or $name
Note : perl5 NE génère PAS une erreur pour le @ terminant $bar
$
ou @
).
@www = "buz"; $foo = "foo"; $bar = "bar"; sub foo { return "bar" }; print "|@{w.w.w}|${main'foo}|";
# perl4 affiche : |@{w.w.w}|foo| # perl5 affiche : |buz|bar|
Notez que vous pouvez utiliser use strict;
pour vous mettre à
l'abri de tels pièges sous perl5.
$$
tout seul
fonctionne toutefois toujours bien.
print "this is $$x\n";
# perl4 affiche : this is XXXx (XXX is the current pid) # perl5 affiche : this is
eval "EXPR"
exige maintenant
soit que les deux $
soient protégés dans la spécification du nom du
hachage, soit que les deux accolades soient protégées. Si les
accolades sont protégées, le résultat sera compatible entre perl4 et
perl5. C'est une pratique très commune qui devrait être modifiée de
façon à utiliser si possible la forme bloc d'eval{}
.
$hashname = "foobar"; $key = "baz"; $value = 1234; eval "\$$hashname{'$key'} = q|$value|"; (defined($foobar{'baz'})) ? (print "Yup") : (print "Nope");
# perl4 affiche : Yup # perl5 affiche : Nope
Changer
eval "\$$hashname{'$key'} = q|$value|";
en
eval "\$\$hashname{'$key'} = q|$value|";
donne le résultat suivant :
# perl4 affiche : Nope # perl5 affiche : Yup
ou, changer pour
eval "\$$hashname\{'$key'\} = q|$value|";
donne le résultat suivant :
# perl4 affiche : Yup # perl5 affiche : Yup # et est compatible avec les deux versions
perl -e '$bar=q/not/; print "This is $foo{$bar} perl5"'
# perl4 affiche : This is not perl5 # perl5 affiche : This is perl5
print "$foo{"
perl 4 affiche : { perl 5 affiche : syntax error
$foo = "array"; print "\$$foo{bar}\n";
# perl4 affiche : $array{bar} # perl5 affiche : $
Perl 5 cherche $array{bar}
qui n'existe pas, mais perl 4 est
content de simplement substituer $foo par ``array''. Faites attention à
cela en particulier dans les eval
's.
qq()
passée à eval
eval qq( foreach \$y (keys %\$x\) { \$count++; } );
# perl4 exécute cela sans problème # perl5 affiche : Can't find string terminator ")"
Pièges généraux de DBM.
dbmopen()
fonctionne correctement sans lien
via tie
vers une implémentation de dbm sous forme d'extension.
dbmopen (%dbm, "file", undef); print "ok\n";
# perl4 affiche : ok # perl5 affiche : ok (IFF linked with -ldbm or -lndbm)
dbmopen(DB, "testdb",0600) || die "couldn't open db! $!"; $DB{'trap'} = "x" x 1024; # valeur trop grande pour la plupart # des dbm/ndbm print "YUP\n";
# perl4 affiche : dbm store returned -1, errno 28, key "trap" at - line 3. YUP
# perl5 affiche : dbm store returned -1, errno 28, key "trap" at - line 3.
Tout le reste.
require
/do
utilisant la valeur de retoursub foo { $rc = do "./do.pl"; return 8; } print &foo, "\n";
Et le fichier do.pl contient l'unique ligne suivante :
return 3;
Exécuter doit.pl donne le résultat suivant :
# perl 4 affiche : 3 (abandonne tôt le sous-programme) # perl 5 affiche : 8
Le comportement est le même si vous remplacez do
par require
.
split
sur une chaîne vide avec une LIMIT spécifiée$string = ''; @list = split(/foo/, $string, 2)
Perl4 retourne une liste à un élément contenant la chaîne vide mais Perl5 retourne une liste vide.
Comme toujours, si certains de ces pièges sont déclarés un jour officiellement comme étant des bugs, ils seront corrigés et retirés.
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions, consultez http://perl.enstimac.fr/.
Roland Trique <roland.trique@uhb.fr>
Personne pour l'instant.
NOM |