Comportement des références différent entre 5.8 et 5.14

Comportement des références différent entre 5.8 et 5.14 - Perl - Programmation

Marsh Posté le 09-03-2013 à 17:54:00    

Bonjour la Communauté :mouarf:
 
Je viens à vous parce que j'ai un léger soucis dans un script Perl conçu autrefois sous Perl 5.6, qui fonctionne nickel sous Perl 5.8 mais qui plante sous la 5.14.
 
L'objectif : migration d'un vieux Linux à un Linux plus récent. Je suis donc en train de tester les comportements de mes programmes personnels et je bloque sur l'un d'eux.
 
J'ai un hash de liste tout bête. Chaque clé du hash est bien évidemment unique et contient une liste de 5 valeurs.
 
J'alimente ce hash à partir d'un fichier txt contenant par ligne "clé, valeur1, valeur2, ..., valeur 5.
 
Mon hash de liste ressemble au final à ceci :
 

Code :
  1. $hash{cle1}[0] = "valeur1";
  2. $hash{cle1}[1] = "valeur2";
  3. $hash{cle1}[2] = "valeur3";
  4. $hash{cle1}[3] = "valeur4";
  5. $hash{cle1}[4] = "valeur5";
  6. ... ... ...
  7. $hash{cle1500}[0] = "valeur1";
  8. $hash{cle1500}[1] = "valeur2";
  9. $hash{cle1500}[2] = "valeur3";
  10. $hash{cle1500}[3] = "valeur4";
  11. $hash{cle1500}[4] = "valeur5";


 
Comme vous le voyez, rien de bien méchant.
 
J'ai 6 hash que j'envoie dans une fonction et, bien entendu, j'utilise les références pour bien retrouver mes petits.
 
Pour les hash de construction simple (hash{clé}->{valeur}), ça se passe super bien.
Pour CE hash de liste (hash{clé}->[valeur]), ça fait planter le script lors de l'appel de la fonction.
 
L'appel de la fonction se fait comme ceci :
 

Code :
  1. TraiteData(\%{$hash_simple1{valeur1}}, \%{$hash_simple2{valeur1}},
  2. \%{$hash_simple3{valeur1}}, \%{$hash_simple4{valeur1}},
  3. \%{$hash_simple5{valeur1}},
  4. \%{$hash_de_liste{valeur1}}) # <--- mon hash de liste


 
Le début de ma fonction TraiteData :
 

Code :
  1. sub TraiteData
  2. {
  3.     my (@hash_simple1, @hash_simple2, @hash_simple3,
  4. @hash_simple4, @hash_simple5, @hash_de_liste);
  5.     (@hash_simple1, @hash_simple2, @hash_simple3,
  6. @hash_simple4, @hash_simple5, @hash_de_liste) = @_;
  7. }


A l'appel de cette fonction, j'ai droit à un "NOT HASH REFERENCE".
 
J'ai isolé les hash un par un et j'ai trouvé que c'était mon hash de liste qui ne passait plus sous Perl 5.14 alors qu'il marche sous 5.8.
 
Qu'y a-t-il de mauvais dans ma syntaxe lorsque j'envoie la référence de mon hash de liste à la fonction ?


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 09-03-2013 à 17:54:00   

Reply

Marsh Posté le 09-03-2013 à 18:19:17    

Je ne comprends rien à ce que tu as fait:  
 

Citation :

Pour les hash de construction simple (hash{clé}->{valeur}), ça se passe super bien.


Dans TraiteData(\%{$hash_simple1{valeur1}},  
ton  %hash_simple1 est défini comment?
$hash_simple1{cle1} (ie valeur1) c'est quoi? un scalaire? une référence a autre chose?
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-03-2013 à 18:50:15    

Mes hash simples sont des hash de hash.
 
Construits comme ceci :
 
$hash{clé1}->{val1}
$hash{clé1}->{val2}
$hash{clé1274}->{val1}
$hash{clé1274}->{val2}
 
etc
 
J'ai en gros par hash de hash une centaine de clés différentes et pour chacune d'elles, une trentaine de valeurs.
 
Mais c'est le hash de liste qui me pose des soucis, pas les hash de hash car j'ai testé les références de chacun et il n'y a que sur le hash de liste que ça bug.
 
Mon hash de liste contient lui aussi une centaine de clés et pour chaque clé, 5 valeurs. C'est construit comme suit :
 
$hash{clé1}[0] = val1
$hash{clé1}[1] = val2
$hash{clé1}[2] = val3
$hash{clé1}[3] = val4
$hash{clé1}[4] = val5
$hash{clé1274}[0] = val1
$hash{clé1274}[1] = val2
$hash{clé1274}[2] = val3
$hash{clé1274}[3] = val4
$hash{clé1274}[4] = val5
 
C'est lui qui passe pas sous Perl 5.14 alors que le compilateur ne sourcillait absolument pas depuis 6 ans sous Perl 5.8.


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 09-03-2013 à 19:50:53    

\%{$hash_de_liste{valeur1}}
ben ça devrait pas être plutôt
\@{$hash_de_liste{valeur1}}
car si %hash_de_liste est un hash de liste, $hash_de_liste{valeur1} est une référence à une liste, et donc on a la liste avec @{$hash_de_liste{valeur1}}
 
Noter que ce que tu fais est verbeux, puisque
\@{$hash_de_liste{valeur1}} et $hash_de_liste{valeur1} sont la même valeur scalaire
 
et idem pour tes \%{$hash_simple1{valeur1} qui sont des scalaires identiques à $hash_simple1{valeur1}
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-03-2013 à 20:03:34    

Je viens de tester rapidement, c'était bien cela:

Code :
  1. my %hs;
  2. $hs{toto}->{tata} = 1;
  3. $hs{toto}->{tutu} = 2;
  4. $hs{toto}->{titi} = 3;
  5.  
  6. my %hl;
  7. $hl{zozo}[0] = 1;
  8. $hl{zozo}[1] = 2;
  9. $hl{zozo}[2] = 3;
  10.  
  11.  
  12. sub TraiteData {
  13.  my (@hash_simple, @hash_de_liste);
  14.  (@hash_simple, @hash_de_liste) = @_;
  15. }
  16.  
  17. TraiteData(\%{$hs{toto}}, \@{$hl{zozo}}); #


ça marche, mais avec TraiteData(\%{$hs{toto}}, \%{$hl{zozo}}); j'ai ton message d'erreur.
Et bien sur,  TraiteData($hs{toto}, $hl{zozo}); marche aussi et est plus simple.
 
A+,


Message édité par gilou le 09-03-2013 à 20:04:32

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 10-03-2013 à 14:40:01    

Merci Gilou d'avoir pris de ton temps pour m'aider !  :jap:  
 
Evidemment, tu as raison et il m'a suffit de remplacer le % devant mon hash de liste par @ pour que ça fonctionne !  :love:  
 
Ce qui signifie donc que Perl 5.6 et 5.8 étaient vachement permissifs sur mon code. Ca ne m'a jamais signalé la moindre erreur dans mes logs (canal STDERR que je redirige dans un fichier).
 
Encore merci !  [:hpfan]


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 11-03-2013 à 13:12:15    

:) Oui, Perl s'est beaucoup amélioré avec les releases récentes et a corrigé pas mal de bugs qui traînaient.
Par exemple, une des améliorations récentes (pour la sécurité) c'est que dorénavant, les clés des hashes sont accédées suivant un ordre aléatoire qui varie avec chaque exécution d'un script.
 
A+,

Message cité 1 fois
Message édité par gilou le 11-03-2013 à 13:12:54

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-03-2013 à 13:19:38    

gilou a écrit :

:) Oui, Perl s'est beaucoup amélioré avec les releases récentes et a corrigé pas mal de bugs qui traînaient.
Par exemple, une des améliorations récentes (pour la sécurité) c'est que dorénavant, les clés des hashes sont accédées suivant un ordre aléatoire qui varie avec chaque exécution d'un script.

A+,


 
Ah ça, ça m'intéresse assez  :)


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 11-03-2013 à 15:32:50    

Citation :

Per process hash randomization  
The seed used by Perl's hash function is now random. This means that the order which keys/values will be returned from functions like keys(), values(), and each() will differ from run to run.  
This change was introduced to make Perl's hashes more robust to algorithmic complexity attacks, and also because we discovered that it exposes hash ordering dependency bugs and makes them easier to track down.

Depuis la 5.17.6
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed