J'ai h=E9sit=E9 =E0 poser la question ici avant de passer un bon moment ave=
c
un coll=E8gue pour comprendre le comportement d'un bout de code (mal)
g=E9n=E9r=E9. Et comme ce n'est pas banal comme probl=E8me, je le poste qua=
nd
m=EAme.
Voici le code mal g=E9n=E9r=E9 - le "if" provient d'une recopie d'expressio=
n
r=E9guli=E8re depuis un fichier de configuration dans un "eval":
my $line=3D'2007/11/14 12:00:20 066 ERROR Exception caught';
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de
configuration des expressions r=E9guli=E8res.
Mais on s'est demand=E9 pourquoi ce code compilait et =E9tait valide (il y =
a
quand m=EAme un warning =E0 l'=E9valuation) et aussi pourquoi la condition =
du
"if" =E9tait toujours vrai...
D=E9sol=E9 mais il n'y a rien =E0 gagner =E0 ce jeu concours ;)
--=20
Yves Martin
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
kurtz le pirate
In article , Yves Martin wrote:
Bonjour,
J'ai hésité à poser la question ici avant de passer un bon moment avec un collègue pour comprendre le comportement d'un bout de code (mal) généré. Et comme ce n'est pas banal comme problème, je le poste quand même.
Voici le code mal généré - le "if" provient d'une recopie d'expression régulière depuis un fichier de configuration dans un "eval":
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de configuration des expressions régulières.
Mais on s'est demandé pourquoi ce code compilait et était valide (il y a quand même un warning à l'évaluation) et aussi pourquoi la condition du "if" était toujours vrai...
oui, un : use of uninitialized value in pattern match (m//) at ... line 8.
le test donne : $& -> "2007" $' -> "/11/14 12:00:20 066 ERROR Exception caught"
je pense (mais je suis très loin d'être un expert) que lors de la recherche, perl trouve la concordance de ^.... avec 2007 (d'ailleurs la valeur de $MATCH et bien "2007" et sort car le / suivant est pour lui la fin de l'expression m// puisqu(il n'est bien sûr pas protégé !
le reste <../.. 05:3 .*ERROR> génère l'erreur.
il faudrait utiliser les Q...E pour "protéger" la chaine. voir perlfaq perlre
:) -- klp
In article <1195218281.21373.63.camel@pcyma>,
Yves Martin <ymartin@nospam.fr> wrote:
Bonjour,
J'ai hésité à poser la question ici avant de passer un bon moment avec
un collègue pour comprendre le comportement d'un bout de code (mal)
généré. Et comme ce n'est pas banal comme problème, je le poste quand
même.
Voici le code mal généré - le "if" provient d'une recopie d'expression
régulière depuis un fichier de configuration dans un "eval":
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de
configuration des expressions régulières.
Mais on s'est demandé pourquoi ce code compilait et était valide (il y a
quand même un warning à l'évaluation) et aussi pourquoi la condition du
"if" était toujours vrai...
oui, un :
use of uninitialized value in pattern match (m//) at ... line 8.
le test donne :
$& -> "2007"
$' -> "/11/14 12:00:20 066 ERROR Exception caught"
je pense (mais je suis très loin d'être un expert) que lors de la
recherche, perl trouve la concordance de ^.... avec 2007 (d'ailleurs la
valeur de $MATCH et bien "2007" et sort car le / suivant est pour lui la
fin de l'expression m// puisqu(il n'est bien sûr pas protégé !
le reste <../.. 05:3 .*ERROR> génère l'erreur.
il faudrait utiliser les Q...E pour "protéger" la chaine.
voir perlfaq perlre
J'ai hésité à poser la question ici avant de passer un bon moment avec un collègue pour comprendre le comportement d'un bout de code (mal) généré. Et comme ce n'est pas banal comme problème, je le poste quand même.
Voici le code mal généré - le "if" provient d'une recopie d'expression régulière depuis un fichier de configuration dans un "eval":
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de configuration des expressions régulières.
Mais on s'est demandé pourquoi ce code compilait et était valide (il y a quand même un warning à l'évaluation) et aussi pourquoi la condition du "if" était toujours vrai...
oui, un : use of uninitialized value in pattern match (m//) at ... line 8.
le test donne : $& -> "2007" $' -> "/11/14 12:00:20 066 ERROR Exception caught"
je pense (mais je suis très loin d'être un expert) que lors de la recherche, perl trouve la concordance de ^.... avec 2007 (d'ailleurs la valeur de $MATCH et bien "2007" et sort car le / suivant est pour lui la fin de l'expression m// puisqu(il n'est bien sûr pas protégé !
le reste <../.. 05:3 .*ERROR> génère l'erreur.
il faudrait utiliser les Q...E pour "protéger" la chaine. voir perlfaq perlre
:) -- klp
Jean-Baptiste Mazon
In article , Yves Martin wrote:
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de configuration des expressions régulières.
Plutôt qu'échapper les `/' on peut aussi changer de délimiteur. Lisibilité à débattre (dans les deux cas). Les goûts et les couleurs...
kurtz le pirate writes:
je pense (mais je suis très loin d'être un expert) que lors de la recherche, perl trouve la concordance de ^.... avec 2007 (d'ailleurs la valeur de $MATCH et bien "2007" et sort car le / suivant est pour lui la fin de l'expression m// puisqu(il n'est bien sûr pas protégé !
le reste <../.. 05:3 .*ERROR> génère l'erreur.
Oui et non. Essaye de définir $_ avant le bloc, et pouf! plus d'erreur ;-)
In article <1195218281.21373.63.camel@pcyma>,
Yves Martin <ymartin@nospam.fr> wrote:
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de
configuration des expressions régulières.
Plutôt qu'échapper les `/' on peut aussi changer de délimiteur.
Lisibilité à débattre (dans les deux cas). Les goûts et les
couleurs...
kurtz le pirate <kurtzlepirate@yahoo.fr> writes:
je pense (mais je suis très loin d'être un expert) que lors de la
recherche, perl trouve la concordance de ^.... avec 2007 (d'ailleurs la
valeur de $MATCH et bien "2007" et sort car le / suivant est pour lui la
fin de l'expression m// puisqu(il n'est bien sûr pas protégé !
le reste <../.. 05:3 .*ERROR> génère l'erreur.
Oui et non.
Essaye de définir $_ avant le bloc, et pouf! plus d'erreur ;-)
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de configuration des expressions régulières.
Plutôt qu'échapper les `/' on peut aussi changer de délimiteur. Lisibilité à débattre (dans les deux cas). Les goûts et les couleurs...
kurtz le pirate writes:
je pense (mais je suis très loin d'être un expert) que lors de la recherche, perl trouve la concordance de ^.... avec 2007 (d'ailleurs la valeur de $MATCH et bien "2007" et sort car le / suivant est pour lui la fin de l'expression m// puisqu(il n'est bien sûr pas protégé !
le reste <../.. 05:3 .*ERROR> génère l'erreur.
Oui et non. Essaye de définir $_ avant le bloc, et pouf! plus d'erreur ;-)
Jerome Quelin
Yves Martin wrote:
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
Mais on s'est demandé pourquoi ce code compilait et était valide (il y a quand même un warning à l'évaluation) et aussi pourquoi la condition du "if" était toujours vrai...
parce que .. est un opérateur valide en perl : c'est l'opérateur flip flop dans une condition. sauf que le flip-flop n'a aucune valeur pratique dans un if, c'est utilisé pour des boucles. perldoc perlop pour plus d'infos sur cet opérateur.
ton expression est donc parsée comme : if ( $line =~ m/^..../ .. /.. 05:3 .*ERROR/ ){
et comme $line a bien 4 caractères, ça matche et ton bloc conditionnel est exécuté.
c'est donc un hasard qui fait que tu matchais 2 caractères (..) au milieu. note que avec 3 points (...) ça aurait marché aussi (autre forme du flip-flop), mais au delà (4 points ....) cela ne marche plus.
cdlt, jérôme --
Yves Martin wrote:
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
Mais on s'est demandé pourquoi ce code compilait et était valide (il y a
quand même un warning à l'évaluation) et aussi pourquoi la condition du
"if" était toujours vrai...
parce que .. est un opérateur valide en perl : c'est l'opérateur flip flop
dans une condition. sauf que le flip-flop n'a aucune valeur pratique dans
un if, c'est utilisé pour des boucles. perldoc perlop pour plus d'infos sur
cet opérateur.
ton expression est donc parsée comme :
if ( $line =~ m/^..../ .. /.. 05:3 .*ERROR/ ){
et comme $line a bien 4 caractères, ça matche et ton bloc conditionnel est
exécuté.
c'est donc un hasard qui fait que tu matchais 2 caractères (..) au milieu.
note que avec 3 points (...) ça aurait marché aussi (autre forme du
flip-flop), mais au delà (4 points ....) cela ne marche plus.
Mais on s'est demandé pourquoi ce code compilait et était valide (il y a quand même un warning à l'évaluation) et aussi pourquoi la condition du "if" était toujours vrai...
parce que .. est un opérateur valide en perl : c'est l'opérateur flip flop dans une condition. sauf que le flip-flop n'a aucune valeur pratique dans un if, c'est utilisé pour des boucles. perldoc perlop pour plus d'infos sur cet opérateur.
ton expression est donc parsée comme : if ( $line =~ m/^..../ .. /.. 05:3 .*ERROR/ ){
et comme $line a bien 4 caractères, ça matche et ton bloc conditionnel est exécuté.
c'est donc un hasard qui fait que tu matchais 2 caractères (..) au milieu. note que avec 3 points (...) ça aurait marché aussi (autre forme du flip-flop), mais au delà (4 points ....) cela ne marche plus.
cdlt, jérôme --
jl_morel
Dans l'article , a dit...
J'ai hésité à poser la question ici avant de passer un bon moment ave >c un collègue pour comprendre le comportement d'un bout de code (mal) généré. Et comme ce n'est pas banal comme problème, je le poste qua >nd même.
Voici le code mal généré - le "if" provient d'une recopie d'expressio >n régulière depuis un fichier de configuration dans un "eval":
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de configuration des expressions régulières.
Mais on s'est demandé pourquoi ce code compilait et était valide (il y >a quand même un warning à l'évaluation) et aussi pourquoi la condition >du "if" était toujours vrai...
Pour compléter ce qui a déjà été dit, on peut utiliser le debugger de regexp intégré à perl. Il suffit d'ajouter use re 'debug'; au debut du script. Avec votre bout de code, on voit que perl compile deux regexps : ( pour les détails voir perldebguts : http://www.bribes.org/perl/docfr/perldebguts.html#LD64431B2 )
Compiling REx `^....' size 6 Got 52 bytes for offset annotations. first at 2 1: BOL(2) 2: REG_ANY(3) 3: REG_ANY(4) 4: REG_ANY(5) 5: REG_ANY(6) 6: END(0) anchored(BOL) minlen 4 Offsets: [6] 1[1] 2[1] 3[1] 4[1] 5[1] 6[0] Compiling REx `.. 05:3 .*ERROR' size 11 Got 92 bytes for offset annotations. first at 1 1: REG_ANY(2) 2: REG_ANY(3) 3: EXACT < 05:3 >(6) 6: STAR(8) 7: REG_ANY(0) 8: EXACT <ERROR>(11) 11: END(0) anchored ` 05:3 ' at 2 floating `ERROR' at 8..2147483647 (checking anchored) minlen 13 Offsets: [11] 1[1] 2[1] 3[6] 0[0] 0[0] 10[1] 9[1] 11[5] 0[0] 0[0] 16[0] Matching REx `^....' against `2007/11/14 12:00:20 066 ERROR Exception caught' Setting an EVAL scope, savestack=5 0 <> <2007/11/14 1> | 1: BOL 0 <> <2007/11/14 1> | 2: REG_ANY 1 <2> <007/11/14 1> | 3: REG_ANY 2 <20> <07/11/14 1> | 4: REG_ANY 3 <200> <7/11/14 1> | 5: REG_ANY 4 <2007> </11/14 1> | 6: END Match successful! Use of uninitialized value in pattern match (m//) at F:tmp_perlREGEXP~4.PL line 8. Freeing REx: `"^...."' Freeing REx: `".. 05:3 .*ERROR"' Match !!
HTH -- J-L.M. http://www.bribes.org/perl
Dans l'article <1195218281.21373.63.camel@pcyma>, ymartin@nospam.fr a dit...
J'ai hésité à poser la question ici avant de passer un bon moment ave >c
un collègue pour comprendre le comportement d'un bout de code (mal)
généré. Et comme ce n'est pas banal comme problème, je le poste qua >nd
même.
Voici le code mal généré - le "if" provient d'une recopie d'expressio >n
régulière depuis un fichier de configuration dans un "eval":
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de
configuration des expressions régulières.
Mais on s'est demandé pourquoi ce code compilait et était valide (il y >a
quand même un warning à l'évaluation) et aussi pourquoi la condition >du
"if" était toujours vrai...
Pour compléter ce qui a déjà été dit, on peut utiliser le debugger de
regexp intégré à perl. Il suffit d'ajouter
use re 'debug';
au debut du script.
Avec votre bout de code, on voit que perl compile deux regexps :
( pour les détails voir perldebguts :
http://www.bribes.org/perl/docfr/perldebguts.html#LD64431B2 )
Compiling REx `^....'
size 6 Got 52 bytes for offset annotations.
first at 2
1: BOL(2)
2: REG_ANY(3)
3: REG_ANY(4)
4: REG_ANY(5)
5: REG_ANY(6)
6: END(0)
anchored(BOL) minlen 4
Offsets: [6]
1[1] 2[1] 3[1] 4[1] 5[1] 6[0]
Compiling REx `.. 05:3 .*ERROR'
size 11 Got 92 bytes for offset annotations.
first at 1
1: REG_ANY(2)
2: REG_ANY(3)
3: EXACT < 05:3 >(6)
6: STAR(8)
7: REG_ANY(0)
8: EXACT <ERROR>(11)
11: END(0)
anchored ` 05:3 ' at 2 floating `ERROR' at 8..2147483647 (checking anchored)
minlen 13
Offsets: [11]
1[1] 2[1] 3[6] 0[0] 0[0] 10[1] 9[1] 11[5] 0[0] 0[0] 16[0]
Matching REx `^....' against `2007/11/14 12:00:20 066 ERROR Exception caught'
Setting an EVAL scope, savestack=5
0 <> <2007/11/14 1> | 1: BOL
0 <> <2007/11/14 1> | 2: REG_ANY
1 <2> <007/11/14 1> | 3: REG_ANY
2 <20> <07/11/14 1> | 4: REG_ANY
3 <200> <7/11/14 1> | 5: REG_ANY
4 <2007> </11/14 1> | 6: END
Match successful!
Use of uninitialized value in pattern match (m//) at F:tmp_perlREGEXP~4.PL
line 8.
Freeing REx: `"^...."'
Freeing REx: `".. 05:3 .*ERROR"'
Match !!
J'ai hésité à poser la question ici avant de passer un bon moment ave >c un collègue pour comprendre le comportement d'un bout de code (mal) généré. Et comme ce n'est pas banal comme problème, je le poste qua >nd même.
Voici le code mal généré - le "if" provient d'une recopie d'expressio >n régulière depuis un fichier de configuration dans un "eval":
my $line='2007/11/14 12:00:20 066 ERROR Exception caught';
L'erreur provient de l'oubli des escapes sur les "/" dans le fichier de configuration des expressions régulières.
Mais on s'est demandé pourquoi ce code compilait et était valide (il y >a quand même un warning à l'évaluation) et aussi pourquoi la condition >du "if" était toujours vrai...
Pour compléter ce qui a déjà été dit, on peut utiliser le debugger de regexp intégré à perl. Il suffit d'ajouter use re 'debug'; au debut du script. Avec votre bout de code, on voit que perl compile deux regexps : ( pour les détails voir perldebguts : http://www.bribes.org/perl/docfr/perldebguts.html#LD64431B2 )
Compiling REx `^....' size 6 Got 52 bytes for offset annotations. first at 2 1: BOL(2) 2: REG_ANY(3) 3: REG_ANY(4) 4: REG_ANY(5) 5: REG_ANY(6) 6: END(0) anchored(BOL) minlen 4 Offsets: [6] 1[1] 2[1] 3[1] 4[1] 5[1] 6[0] Compiling REx `.. 05:3 .*ERROR' size 11 Got 92 bytes for offset annotations. first at 1 1: REG_ANY(2) 2: REG_ANY(3) 3: EXACT < 05:3 >(6) 6: STAR(8) 7: REG_ANY(0) 8: EXACT <ERROR>(11) 11: END(0) anchored ` 05:3 ' at 2 floating `ERROR' at 8..2147483647 (checking anchored) minlen 13 Offsets: [11] 1[1] 2[1] 3[6] 0[0] 0[0] 10[1] 9[1] 11[5] 0[0] 0[0] 16[0] Matching REx `^....' against `2007/11/14 12:00:20 066 ERROR Exception caught' Setting an EVAL scope, savestack=5 0 <> <2007/11/14 1> | 1: BOL 0 <> <2007/11/14 1> | 2: REG_ANY 1 <2> <007/11/14 1> | 3: REG_ANY 2 <20> <07/11/14 1> | 4: REG_ANY 3 <200> <7/11/14 1> | 5: REG_ANY 4 <2007> </11/14 1> | 6: END Match successful! Use of uninitialized value in pattern match (m//) at F:tmp_perlREGEXP~4.PL line 8. Freeing REx: `"^...."' Freeing REx: `".. 05:3 .*ERROR"' Match !!