IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

[PERL] problème désallocation de variable


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Par défaut [PERL] problème désallocation de variable
    Bonjour,
    Voilà mon problème:
    J'ai une variable (variable Commande) qui est définie dans une fonction qui appartient à un package, comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    package TX2::BD;
     
    sub WEBSELECT()
    {
          my $dbi=$_[0];
          my $requete=$_[1];
          my $sens=$_[2];
     
          our @ChampsCommande;
          our @Commande;
     
          if($sens eq 'trsnddoc')
          {
                @ChampsCommande=qw/DATE_CREATION_DOC HEURE_CREATION_DOC DATE_ENVOI_DOC HEURE_ENVOI_DOC NUM_INTERCHANGE NUM_CONTROL_DOC NUM_MESSAGE CODE_STATUT_1 CODE_STATUT_2 CODE_ERREUR NUM_ACK_RESEAU *** ADDRESSE_EMETTEUR ADDRESSE_DESTINATAIRE CONNEXION TYPE_MESSAGE VERSION /;
          }
          else
          {
                @ChampsCommande=qw/DATE_CREATION_DOC HEURE_CREATION_DOC DATE_RECEPTION_DOC HEURE_RECEPTION_DOC DATE_TRADUCTION HEURE_TRADUCTION NUM_INTERCHANGE NUM_CONTROL_DOC NUM_MESSAGE CODE_STATUT_1 CODE_STATUT_2 CODE_ERREUR ADDRESSE_EMETTEUR ADDRESSE_DESTINATAIRE CONNEXION TYPE_MESSAGE VERSION /;
          }
          my $i;
          my $req=$dbi->prepare($requete);
          $req->execute(); 
           while (my $ref = $req->fetchrow_hashref()) 
          { 
                @{$Commande[$i]}{@ChampsCommande}=@$ref{@ChampsCommande};
     
          $i++;
          } 
          $req->finish;
    }
    La variable Commande est déclarée avec our, pour pouvoir la partagée, y accéder d'un autre script.

    Dans le fichier suivant, je fais appel à cette fonction pour réaliser deux requêtes sur deux tables différentes.

    Voici le fichier en question (la partie qui intéresse):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
     
    %TrySens=(trsnddoc=>['ADDRESSE_EMETTEUR','ADDRESSE_DESTINATAIRE'],
              trrcvdoc=>['ADDRESSE_DESTINATAIRE','ADDRESSE_EMETTEUR'],
              );
     
     
    %trsnddoc=(Addresse=>'ADDRESSE_DESTINATAIRE',
               Date=>'DATE_ENVOI_DOC',
               Heure=>'HEURE_ENVOI_DOC',
               Statut1=>'CODE_STATUT_1',
               Statut2=>'CODE_STATUT_2',
    );
     
    %trrcvdoc=(Addresse=>'ADDRESSE_EMETTEUR',
               Date=>'DATE_RECEPTION_DOC',
               Heure=>'HEURE_RECEPTION_DOC',
               Statut1=>'CODE_STATUT_1',
    );
     
    %MyChamps=('trsnddoc'=>\%trsnddoc,'trrcvdoc'=>\%trrcvdoc,);
    %Titre=('trsnddoc'=>'sent','trrcvdoc'=>'received',);
     
    ###########################################################################################
     
     
     
    print "<HEAD>\n";
    print "<link rel='stylesheet' href='../style.css' type='text/css' media='screen' />\n";
    print "<script language=\"javascript\" src=\"../script2.js\" type=\"text/javascript\"></script>\n";
    print "</HEAD>\n";
    print "<HTML><BODY class='Body2'>";
     
    $dbh=&TX2::BD::Connexion();
          foreach my $keys(keys %TrySens)
          {
              $Sens=$keys;
              $Requete="SELECT * FROM $keys WHERE NUM_MESSAGE like \'%$Request%\' AND NUM_MESSAGE!=''";
              if(@{$compte}[0] ne $TX2::Variable::admin)
              {
                      &MakeWhichCompte($keys,@{$TrySens{$keys}}[0],@{$TrySens{$keys}}[1]);    
                      $Requete.=$WhichCompte;
                      #print "<BR>$Requete<BR>";
                      for(my $j=0;$j<=$#TX2::BD::Commande;$j++)
                      {
                          for(my $k=0;$k<=($#TX2::BD::ChampsCommande);$k++)
                          {
                            delete($TX2::BD::Commande[$j]{$TX2::BD::ChampsCommande[$k]});
                          }
                      }
              }
     
              &TX2::BD::WEBSELECT($dbh,$Requete,$Sens);
     
              &DisplayRequest();
          }
    &TX2::BD::Deconnexion($dbh);
    Lors de la premère requête, je retourne, on va dire, 30 valeurs (ça c bon), mais lors de la seconde connexion(sur l'autre table), je devrais retourner par exemple 10 valeur mais j'en retourne 30. 10 enregistrements qui proviennent de la seconde table et les 20 autres qui viennent de la précédente.

    C'est sûr, ma variable Commande garde en mémoire les valeurs précédentes. alors j'ai rajouté ce petit bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for(my $j=0;$j<=$#TX2::BD::Commande;$j++)
                      {
                          for(my $k=0;$k<=($#TX2::BD::ChampsCommande+1);$k++)
                          {
                            delete($TX2::BD::Commande[$j]{$TX2::BD::ChampsCommande[$k]});
                          }
                      }
    pour supprimer chaque clé après une requête. Mais ça, ça me supprime la valeur de mes clés !!!! et non la clé
    Ce qui fait que je me retrouve toujours avec un résultat de 30 enregistrements pour la première requetes et 30 enregitrements pour la seconde dont 20 sans valeurs !!!!!!!


    S'il vous pait, comment faire pour règler ce problème

    Merci pour votre aide !!! et bonne soirée

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Par défaut
    siou plait , pouvez vous m'aider ???

  3. #3
    Membre expérimenté
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Par défaut
    Au lieu d'utiliser des variables globales, qui sont le Mal, tu devrais renseigner un array ou hash tout neuf dans WEBSELECT(), et renvoyer cette variable.

    Ce n'est pas comme en C, il ne va pas disparaître à la fin de la fonction. Celui qui l'appel va recevoir un array nickel, sans enregistrements superflus.

    N

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Par défaut
    Je ne sais pas comment renvoyer cet array. Enfin plutôt, je ne sais pas comment renvoyer un tableau de tableaux de hachage. C'est ce qu'est la variable %Commande je crois.

    J'avais essayer mais sans succès, c'est pour ça que j'ai déclaré cette variable globalement.

    Sais tu comment je pourrais renvoyer cette variable proprement ??

    Et l'utiliser dans mon script comme il faut ?

    Merci pour ton aide.

  5. #5
    Jeh
    Jeh est déconnecté
    Membre expérimenté Avatar de Jeh
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 203
    Par défaut
    Citation Envoyé par LE NEINDRE
    Je ne sais pas comment renvoyer cet array. Enfin plutôt, je ne sais pas comment renvoyer un tableau de tableaux de hachage. C'est ce qu'est la variable %Commande je crois.

    J'avais essayer mais sans succès, c'est pour ça que j'ai déclaré cette variable globalement.

    Sais tu comment je pourrais renvoyer cette variable proprement ??

    Et l'utiliser dans mon script comme il faut ?

    Merci pour ton aide.
    Pour renvoyer, ton tableau :
    (utiliser un pointeur sur ton tableau, c'est mieux).
    Et au lieu d'utiliser ton tableau comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $TX2::BD::Commande[$j]{$TX2::BD::ChampsCommande[$k]}
    Tu fais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $TX2::BD::Commande->[$j]{$TX2::BD::ChampsCommande[$k]}
    Idem pour ChampsCommande.
    Et dans ce cas, il fait déclarer tes variables en local (avec "my" et non "our"). Tu gagnes ainsi en sécurité car tes variables ne peuvent être modifiées en cours d'éxecution.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Par défaut
    Citation Envoyé par Jeh
    Pour renvoyer, ton tableau :
    (utiliser un pointeur sur ton tableau, c'est mieux).
    Et au lieu d'utiliser ton tableau comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $TX2::BD::Commande[$j]{$TX2::BD::ChampsCommande[$k]}
    Tu fais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $TX2::BD::Commande->[$j]{$TX2::BD::ChampsCommande[$k]}
    Idem pour ChampsCommande.
    Et dans ce cas, il fait déclarer tes variables en local (avec "my" et non "our"). Tu gagnes ainsi en sécurité car tes variables ne peuvent être modifiées en cours d'éxecution.
    Je vais essayer de déclarer ma variable commande en local et donc il faudra que je la renvoi en faisant return \@commande.
    Mais si je fais ça je n'aurais plus accès à ma variable de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $TX2::BD::Commande[$j]{$TX2::BD::ChampsCommande[$k]}
    ou de celle ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $TX2::BD::Commande->[$j]{$TX2::BD::ChampsCommande[$k]}
    puisque %commande sera définie localement par my et plus "globalement" par our ?


    non ?

  7. #7
    Membre averti
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    16
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2005
    Messages : 16
    Par défaut
    si, tu peux récupérer ta variable puisque dans ta fonction du fais un "return".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    fonc1 {
    my val1;
    ...
    return \@val1;
    }
     
    fonc2 {
    my $val1-1;
     
    $val1-1 = fonc1(); # $val1-1 est l'@ de $val1, si je dis pas de bétises
     
    }
    ou quelque chose comme çà. Il faut comprendre un minimum les références--> voir les tuto, et autres doc

    [Edit]Balises [ code ] et [ /code ] ajoutées par 2Eurocents ...
    Merci d'y penser pour améliorer la lisibilité du Forum[/Edit]

  8. #8
    Jeh
    Jeh est déconnecté
    Membre expérimenté Avatar de Jeh
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 203
    Par défaut
    Citation Envoyé par LE NEINDRE
    Citation Envoyé par Jeh
    Pour renvoyer, ton tableau :
    (utiliser un pointeur sur ton tableau, c'est mieux).
    Et au lieu d'utiliser ton tableau comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $TX2::BD::Commande[$j]{$TX2::BD::ChampsCommande[$k]}
    Tu fais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $TX2::BD::Commande->[$j]{$TX2::BD::ChampsCommande[$k]}
    Idem pour ChampsCommande.
    Et dans ce cas, il fait déclarer tes variables en local (avec "my" et non "our"). Tu gagnes ainsi en sécurité car tes variables ne peuvent être modifiées en cours d'éxecution.
    Je vais essayer de déclarer ma variable commande en local et donc il faudra que je la renvoi en faisant return \@commande.
    Mais si je fais ça je n'aurais plus accès à ma variable de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $TX2::BD::Commande[$j]{$TX2::BD::ChampsCommande[$k]}
    ou de celle ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $TX2::BD::Commande->[$j]{$TX2::BD::ChampsCommande[$k]}
    puisque %commande sera définie localement par my et plus "globalement" par our ?


    non ?
    Oui oui, tout à fait. J'ai oublié d'enlever "TX2::BD::"...
    Si la variable renvoyée par ta fonction se nomme $Commande, tu devras t'en servir ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $Commande->[$j]{$TX2::BD::ChampsCommande[$k]}

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Par défaut
    Si la variable renvoyée par ta fonction se nomme $Commande, tu devras t'en servir ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $Commande->[$j]{$TX2::BD::ChampsCommande[$k]}
    Ok, alors donc %ChampsCommande sera toujours déclaré globalement par la déclaration "our".

    Je tente, et je te dis.

    Merci pour ton aide !!

  10. #10
    Jeh
    Jeh est déconnecté
    Membre expérimenté Avatar de Jeh
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 203
    Par défaut
    Encore désolé. C'est le même topo pour ChampsCommande. Il faut que tu le retournes que tu l'utilises comme l'autre. Il faut banir les "our".

  11. #11
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Les "our" généralement, on ne les utilises que pour des constantes qu'on veut exporter, les autres cas c'est pour ceux qui savent vraiment ce qu'ils font.

    --
    Jedaï

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Par défaut
    Yeaahh, c'est génial, ça marche !!!
    J'ai donc fait dans la fonction WEBSELECT du package:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
     
    sub WEBSELECT()
    {
          my $dbi=$_[0];
          my $requete=$_[1];
          my $sens=$_[2];
          my @Result;
          my @ChampsCommande;
          my @Commande;
     
          if($sens eq 'trsnddoc')
          {
                @ChampsCommande=qw/DATE_CREATION_DOC HEURE_CREATION_DOC DATE_ENVOI_DOC HEURE_ENVOI_DOC NUM_INTERCHANGE NUM_CONTROL_DOC NUM_MESSAGE CODE_STATUT_1 CODE_STATUT_2 CODE_ERREUR NUM_ACK_RESEAU *** ADDRESSE_EMETTEUR ADDRESSE_DESTINATAIRE CONNEXION TYPE_MESSAGE VERSION /;
          }
          else
          {
                @ChampsCommande=qw/DATE_CREATION_DOC HEURE_CREATION_DOC DATE_RECEPTION_DOC HEURE_RECEPTION_DOC DATE_TRADUCTION HEURE_TRADUCTION NUM_INTERCHANGE NUM_CONTROL_DOC NUM_MESSAGE CODE_STATUT_1 CODE_STATUT_2 CODE_ERREUR ADDRESSE_EMETTEUR ADDRESSE_DESTINATAIRE CONNEXION TYPE_MESSAGE VERSION /;
          }
          my $i;
          my $req=$dbi->prepare($requete);
          $req->execute(); 
           while (my $ref = $req->fetchrow_hashref()) 
          { 
                @{$Commande[$i]}{@ChampsCommande}=@$ref{@ChampsCommande};
     
          $i++;
          } 
          $req->finish;
    $Result[0]=\@Commande;
    $Result[1]=\@ChampsCommande;
    return \@Result;
    }
    J'ai fait un tableau résult de longueur 2 et comportant les 2 références des tableaux que je veux renvoyer.
    Ensuite je retourne la référence du tableau construit.

    Et dans mon cgi, pour afficher le résultat de la requête, je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    $SELECT=&TX2::BD::WEBSELECT($dbh,$Requete,$Sens);
              $Commandes=$SELECT->[0];
              $champs=$SELECT->[1];
              foreach(my $i=0;$i<=$#{$Commandes};$i++)
              {
                  foreach(@{$champs})
                  {
                        print "$Commandes->[$i]{$_}\n";
                  }
              }
    Je récupére la référence di tableau retourné dans $SELECT, récupére ensuite les deux références des tableaux que je voulais. Puis j'affiche avec deux boucles.

    Jeh, merci beaucoup
    Je n'aurai pas réussi je crois sans tes explications

    Bonne journée à tous (je suis content de metrte ce tag résolu !!!)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PERL] problème avec une variable de session PHP
    Par ingeston dans le forum Modules
    Réponses: 1
    Dernier message: 18/04/2012, 16h32
  2. Shell et perl problème d'interpolation de variable.
    Par Whaouu dans le forum Langage
    Réponses: 7
    Dernier message: 26/10/2005, 17h39
  3. Réponses: 5
    Dernier message: 31/08/2005, 10h05
  4. Problèmes avec les variables final
    Par casolaro dans le forum Langage
    Réponses: 7
    Dernier message: 09/12/2004, 14h29
  5. Réponses: 6
    Dernier message: 28/05/2004, 09h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo