# Perl5,pb: affectation d'un hashage dans une boucle. trivial?

**URL:** <https://www.debian-fr.org/t/perl5-pb-affectation-dun-hashage-dans-une-boucle-trivial/60080>\
**Category:** Programmation\
**Created:** [Février 21, 2016, 7:02 UTC](https://www.debian-fr.org/t/perl5-pb-affectation-dun-hashage-dans-une-boucle-trivial/60080 "2016-02-21T19:02:49Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Février 21, 2016, 7:02 UTC](https://www.debian-fr.org/t/perl5-pb-affectation-dun-hashage-dans-une-boucle-trivial/60080/1 "2016-02-21T19:02:49Z")

</div>

Bonjour,

😠 comme toujours après une trop longue pause entre 2 séquences de programmation Perl ( Perl5 ), je me heurte à un bug trivial.

[code]my @CHAMPS=qw( COMITE NOM DATE MISSION RAPPORT CONCLUSION CERTIFIE NOTE RAPPEL ) ;  
my %CHAMPS\_pour; # La variable de base !  
my @lettres=qw( A B C );

### @CHAMPS

### @lettres

foreach my $nom ( @CHAMPS ) {  
say $nom;

```
while ( my $lettre=shift(@lettres) ) {
    ### $lettre
    my $cle="$nom"."$lettre";
    $CHAMPS_pour{$cle}="$nom".'-'."$lettre" ;
};

```

};[/code]

sans la boucle while, la boucle foreach parcourt bien tout le tableau @CHAMPS ( DE COMITE à RAPPEL )  
Avec la boucle while, seul le 1er élément (COMITE) semble parcouru.( la boucle while fonctionne avec cet élément )

[size=85]L’ affichage des variables est réalisé au fur et à mesure avec les commentaires «&nbsp;### $var&nbsp;» du module Smart::Comments[/size]

[size=85]J’ai écrit cette portion de programme pour tenter de comprendre le BUG d’un script plus élaboré, ce qui explique le caractère sinon absurde de sa fonction.[/size]

Merci pour votre aide ( et pour votre bienveillante compréhension.. )

[edit] le titre initial

> [@](#):
>
> imbriquer while dans foreach

est sans doute faux

je le remplace par

> [@](#):
>
> Affectation d’un hachage dans une boucle

et je m’explique:

1 Le code:  
( j’ai mis en sous-programme la boucle while, et ajouter des affichages de variables )

[code]#!/usr/bin/perl -w  
use 5.010;  
use warnings;  
use strict;  
use diagnostics;  
use Smart::Comments ;

my @CHAMPS=qw( COMITE NOM DATE ) ;  
my %CHAMPS\_pour; # La variable de base !  
my @lettres=qw( A B C );

### @CHAMPS

### @lettres

foreach my $nom ( @CHAMPS ) {  
### $nom;  
### appel à assembler sur: $nom  
assembler($nom);  
};

sub assembler {  
my ($N)=@\_ ;  
### assembler avec : $N  
while ( my $lettre=shift(@lettres) ) {  
### assembler: $N  
### while avec: $lettre  
my $cle=«&nbsp;$N&nbsp;».«&nbsp;$lettre&nbsp;»;  
### $cle  
my $val=«&nbsp;$N&nbsp;».‹&nbsp;-&nbsp;›.«&nbsp;$lettre&nbsp;»  
$CHAMPS\_pour{$cle} = $val ; # L’erreur survient ici  
### $CHAMPS\_pour{$cle}  
};  
return;  
}

### %CHAMPS\_pour[/code]

2 L’affichage: les lignes du type ### $cle ou ### %CHAMPS\_pour affichent les variables comme print (scalaires) ou comme Dumper ( tableaux, hashages )

[code]./hashage.pl

### @CHAMPS: [

### ‹&nbsp;COMITE&nbsp;›,

### ‹&nbsp;NOM&nbsp;›,

### ‹&nbsp;DATE&nbsp;›

### ]

### @lettres: [

### ‹&nbsp;A&nbsp;›,

### ‹&nbsp;B&nbsp;›,

### ‹&nbsp;C&nbsp;›

### ]

### $nom: ‹&nbsp;COMITE&nbsp;›

### appel à assembler sur: ‹&nbsp;COMITE&nbsp;›

### assembler avec : ‹&nbsp;COMITE&nbsp;›

### assembler: ‹&nbsp;COMITE&nbsp;›

### while avec: ‹&nbsp;A&nbsp;›

### $cle: ‹&nbsp;COMITEA&nbsp;›

### $val: ‹&nbsp;COMITE-A&nbsp;›

### $CHAMPS\_pour{$cle} L’ERREUR APPARAÎT ICI

```
                   (attendu: COMITE-A, résultat de l'affectation de $CHAMPS_pour{COMITEA} )

```

### assembler: ‹&nbsp;COMITE&nbsp;›

### while avec: ‹&nbsp;B&nbsp;›

### $cle: ‹&nbsp;COMITEB&nbsp;›

### $val: ‹&nbsp;COMITE-B&nbsp;›

### $CHAMPS\_pour{$cle}

### assembler: ‹&nbsp;COMITE&nbsp;›

### while avec: ‹&nbsp;C&nbsp;›

### $cle: ‹&nbsp;COMITEC&nbsp;›

### $val: ‹&nbsp;COMITE-C&nbsp;›

### $CHAMPS\_pour{$cle}

### $nom: ‹&nbsp;NOM&nbsp;›

### appel à assembler sur: ‹&nbsp;NOM&nbsp;›

### assembler avec : ‹&nbsp;NOM&nbsp;›

### $nom: ‹&nbsp;DATE&nbsp;›

### appel à assembler sur: ‹&nbsp;DATE&nbsp;›

### assembler avec : ‹&nbsp;DATE&nbsp;›

### %CHAMPS\_pour: {

### COMITEA =\> ‹&nbsp;COMITE-A&nbsp;›,

### COMITEB =\> ‹&nbsp;COMITE-B&nbsp;›,

### COMITEC =\> ‹&nbsp;COMITE-C&nbsp;›

### }

[/code]

L’ affichage

> [@](#):
>
> ### $CHAMPS\_pour{$cle}

montre que l’affectation ne se fait pas ( Pourtant elle a été faite 1 fois, avec le 1er tour de boucle foreach, comme l’indique l’affichage final de %CHAMPS\_pour )

Dans l’état actuel de ma compréhension limitée, ma question est donc pourquoi la ligne du type:

`$CHAMPS_pour{$cle}=$val`  
n’ utilise-t-elle pas la valeur de $cle pour affecter la valeur à cette clé ?

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Février 21, 2016, 7:02 UTC](https://www.debian-fr.org/t/perl5-pb-affectation-dun-hashage-dans-une-boucle-trivial/60080/2 "2016-02-21T19:02:51Z")

</div>

2 Tests qui fonctionnent comme attendu:

Le 1er, avec foreach:

[code]my @CHAMPS=qw( COMITE NOM DATE ) ;  
my %CHAMPS\_pour ; # La variable de base !  
my @lettres=qw( A B C );

## @CHAMPS

## @lettres

foreach my $champs ( @CHAMPS ) {  
my $cle=‘cle\_’."$champs" ;  
$CHAMPS\_pour{$cle}=$champs ;  
### %CHAMPS\_pour  
};[/code]

Le 2e avec while:

[code]my @CHAMPS=qw( COMITE NOM DATE ) ;  
my %CHAMPS\_pour ; # La variable de base !  
my @lettres=qw( A B C );

## @CHAMPS

## @lettres

while ( my $champs=shift @CHAMPS ) {  
my $cle=‘cle\_’."$champs" ;  
$CHAMPS\_pour{$cle}=$champs ;  
### %CHAMPS\_pour  
};[/code]

Les 2 affichent exactement la même chose, attendue:

[code]

### %CHAMPS\_pour: {

### cle\_COMITE =\> ‘COMITE’

### }

### %CHAMPS\_pour: {

### cle\_COMITE =\> ‘COMITE’,

### cle\_NOM =\> ‘NOM’

### }

### %CHAMPS\_pour: {

### cle\_COMITE =\> ‘COMITE’,

### cle\_DATE =\> ‘DATE’,

### cle\_NOM =\> ‘NOM’

### [/code]}

Jusqu’ici je ne vois pas où est mon BUG

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Février 21, 2016, 7:02 UTC](https://www.debian-fr.org/t/perl5-pb-affectation-dun-hashage-dans-une-boucle-trivial/60080/3 "2016-02-21T19:02:52Z")

</div>

![:confusion-confused:](https://www.debian-fr.org/uploads/default/original/1X/39333d27926e4c2e24d3a43fa8f7cc1bd60b5864.gif "Confused") Autre présentation, peut-être plus lisible, du même bug:

[code]my $scalaire;  
my @tableau= qw( un deux trois );  
my %hashage;

$scalaire=‘valeur’;

### $scalaire

$hashage{cle1} = $scalaire;

### %hashage;

foreach my $new ( ‘Nouveau1’ , ‘nouveau2’ ) {  
### $new  
while ( my $a = shift @tableau ) {  
### $a  
#my $new = ‘Nouveau’;  
$hashage{$a}=$new;

```
    ### @tableau
};
### @tableau
### %hashage

```

}; # fin de foreach  
[/code]

qui renvoie:

[code]### $scalaire: ‘valeur’

### %hashage;

### $new: ‘Nouveau1’

### $a: ‘un’

### @tableau: [

### ‘deux’,

### ‘trois’

### ]

### $a: ‘deux’

### @tableau: [

### ‘trois’

### ]

### $a: ‘trois’

### @tableau: []

### @tableau: []

### %hashage: {

### cle1 =\> ‘valeur’,

### deux =\> ‘Nouveau1’,

### trois =\> ‘Nouveau1’,

### un =\> ‘Nouveau1’

### }

### $new: ‘nouveau2’

### @tableau: []

### %hashage: {

### cle1 =\> ‘valeur’,

### deux =\> ‘Nouveau1’,

### trois =\> ‘Nouveau1’,

### un =\> ‘Nouveau1’

### }

[/code]

On voit que seule le 1er élément du tableau exploré par foreach semble être passé à la boucle while

Aucune erreur (de syntaxe) n’est signalée par warning , strict ou diagnostics.  
Il y a donc vraisemblablement une erreur de logique qui m’échappe.  
Espace de nom ? mes tests n’ont rien trouvé.

Je rame à en creuser la falaise ! ![:angry-banghead:](https://www.debian-fr.org/uploads/default/original/1X/03590d98a359a447ce7713c78201cdb8a8cfdb6b.gif "Bang Head")

---

<div class="post-metadata">

**Author:** ![josephtux](https://www.debian-fr.org/user_avatar/www.debian-fr.org/josephtux/32/3985_2.png) [@josephtux](https://www.debian-fr.org/u/josephtux)\
**Post date:** [Février 21, 2016, 7:02 UTC](https://www.debian-fr.org/t/perl5-pb-affectation-dun-hashage-dans-une-boucle-trivial/60080/4 "2016-02-21T19:02:52Z")

</div>

Et en inversant l’imbricaion des boucles ( foreach dans un while ), je rencontre la même limite:

[code]my $scalaire;  
my @tableau= qw( un deux trois );  
my %hashage;  
my @table\_de\_hashage;

$scalaire=‘valeur’;

### $scalaire

$hashage{cle1} = $scalaire;

### %hashage;

while ( my $a = shift @tableau ) {  
### $a  
foreach my $new ( ‘Nouveau1’ , ‘nouveau2’ ) {  
### $new  
$hashage{$new}=$a;  
### %hashage  
push @table\_de\_hashage, %hashage;  
}; # fin de foreach  
}; # Fin de while  
### @table\_de\_hashage[/code]

Une seule affectation du tableau de hashage a été faite correctement ( les autres sont créées, mais vides ):

[code]### $scalaire: ‘valeur’

### %hashage;

### $a: ‘un’

### $new: ‘Nouveau1’

### %hashage: {

### Nouveau1 =\> ‘un’,

### cle1 =\> ‘valeur’

### }

### $new: ‘nouveau2’

### %hashage: {

### Nouveau1 =\> ‘un’,

### cle1 =\> ‘valeur’,

### nouveau2 =\> ‘un’

### }

### $a: ‘deux’

### $new: ‘Nouveau1’

### %hashage: {

### Nouveau1 =\> ‘deux’,

### cle1 =\> ‘valeur’,

### nouveau2 =\> ‘un’

### }

### $new: ‘nouveau2’

### %hashage: {

### Nouveau1 =\> ‘deux’,

### cle1 =\> ‘valeur’,

### nouveau2 =\> ‘deux’

### }

### $a: ‘trois’

### $new: ‘Nouveau1’

### %hashage: {

### Nouveau1 =\> ‘trois’,

### cle1 =\> ‘valeur’,

### nouveau2 =\> ‘deux’

### }

### $new: ‘nouveau2’

### %hashage: {

### Nouveau1 =\> ‘trois’,

### cle1 =\> ‘valeur’,

### nouveau2 =\> ‘trois’

### }

### @table\_de\_hashage: [

### {

### Nouveau1 =\> ‘trois’,

### cle1 =\> ‘valeur’,

### nouveau2 =\> ‘trois’

### },

### $VAR1-\>[0][0],

### $VAR1-\>[0][0],

### $VAR1-\>[0][0],

### $VAR1-\>[0][0],

### $VAR1-\>[0][0]

### ]

[/code]

ça avance, mais toujours dans la falaise ![:character-smurfgrandpa:](https://www.debian-fr.org/uploads/default/original/1X/8bdbc3a9b2219dc92fe3cf764d0f45b3078b8d01.gif "Grandpa Smurf")
