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 :

[langage] Comment gérer efficacement un debugging ???


Sujet :

Langage Perl

  1. #1
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut [langage] Comment gérer efficacement un debugging ???
    Salut

    J'ai crée un script qui commence à être relativement complexe.

    Comme l'utilisation du debugger perl n'est à la fois pas simple et pas suffisante dans mon cas, j'ai intégré des print conditionnels un peu partout dans mon code qui fonctionnent lorsqu'un parametre debug =1. Rien que du classique en somme.

    Je redirige également les sortie standard et d'erreur sur un fichier de log :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    open STDOUT (>>fichier)
    open STDDERR (>>fichier)
    Rien que du standard.

    Par contre, j'aimerai bien différencier les messages d'erreurs du reste des messages de log, par exemple en les faisant précéder de "WARNING", "ERROR", ou autre selon le type d'erreur, et ce sans faire un die après chaque fonction.

    De plus, les messages d'erreur sont insérés dans le fichier instantannément, mais pas les messages de log généré par un print. Ce qui induit une désynchronisation de la chronologie des messages, et donc rend l'affichage des erreurs inutile.

    Je pense que cela est dû à la gestion des buffers. Est-ce bien un autoflush() qu'il me faudrait utiliser pour vider les buffers ?

    Est-ce que quelqu'un aurait une idée ?

    Merci d'avance.

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 583
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 583
    Points : 2 031
    Points
    2 031
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    open STDOUT (">>fichier1");
    open STDDERR (">>fichier2");
     
    # afficher sur STDOUT
    print "Ca marche pas !";
     
    # afficher sur STDERR
    warn "Ca marche pas !";
    Warn() s'utilise comme un die(), elle affiche une chaîne de caractères sur le canal standard d'erreur. Par contre, elle ne kill pas ton programme.

  3. #3
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut
    Salut Archior

    Merci pour ta réponse

    Par contre, comme exprimé dans mon poste, je ne souhaite pas mettre un die ou un warn à chaque ligne du code, mais capturer un message d'erreur lorsqu'il survient, genre "use uninitialised ......"

    Avec
    print STDERR, ">>fichier"
    ca marche bien, sauf qu'il faut s'accrocher en lisant le log fichier pour s'avoir quelle ligne est un message d'erreur et quelle autre est un message de commentaire dû à un print.

    Donc je voudrais juste faire précéder d'un mot clé les erreurs interceptées

    Pas d'idée non plus sur l'autoflush() ????

    Merci

    FMJ

  4. #4
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 583
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 583
    Points : 2 031
    Points
    2 031
    Par défaut
    Vu que tes print ne bossent (si besoin) que lorsque ton flag DEBUG == 1, rien ne t'empêche de faire des print sur STDERR en différençiant les avertissements des erreurs génantes, comme par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print STDERR "WARNING : blablabla";
    print STDERR "ERR : blablabla";
    A la fin de ton traitement, ton prog relis le log et te ressort toutes les lignes commençant par WARNING || ERR comme par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    open(LOG, "fichier");
    while(<LOG>)
    {
        if (/^(WARNING|ERR) : (.*)/)
        {
            print "$1 ---> $2";
        }
    }
    close(LOG);
    Pour l'autoflush, il me semble qu'il existe une variable implicite en Perl permettant de gérer l'autoflush juste en changeant la valeur initiale de la variable.

    Sinon, il y a le module autoflush mais là, c'est de l'objet et ça peut s'avérere lourdingue à faire gérer par ton prog si celui-ci bosse déjà pas mal sur son traitement principal.

  5. #5
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 583
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 583
    Points : 2 031
    Points
    2 031
    Par défaut
    En lisant la doc Perl, section Perlop, je suis tombé sur ceci :

    Depuis la version v5.6.0, Perl tente de vider les tampons de tous les fichiers ouverts en écriture avant de lancer la commande
    mais cela n’est pas supporté sur toutes les plates-formes (voir le manuel perlport). Pour être plus sûr, vous devriez positionné
    la variable $| ($AUTOFLUSH en anglais) ou appelé la méthode autoflush() des objets IO::Handle pour chacun des
    descripteurs ouverts.


    Si ça peut t'aider davantage ...

  6. #6
    Expert éminent
    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
    Points : 8 586
    Points
    8 586
    Par défaut
    Effectivement, il faut utiliser $|, ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select( (select( HANDLE ), $|=1)[0] );
    Avec cette commande, l'autoflush de HANDLE sera activé.
    Par ailleurs je ne suis pas sûr de très bien comprendre ton autre question ? Pourrais tu être plus précis sur pourquoi tu ne désires pas utiliser "warn" ou même une fonction perso du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    sub perror {
      print STDERR "ERR : ", $_[0];
    }
    sub pwarn {
      print STDERR "WARNING : ", $_[0];
    }
    :
    --
    Jedai

  7. #7
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut
    Merci Jedai et Arioch pour vos réponses.

    Mais soit je me fais mal comprendre, soit je suis trop nul pour voir l'évidence.

    Avant de créer un fichier log, je faisais un copier-coller du STDOUT, i.e. le prompt DOS à partir duquel je lançais le script.
    Cela me permettait d'avoir à la fois les messages de commentaire que j'ai inséré dans le code (compteurs de boucle, flags, valeurs de certaines variables, etc.) ainsi que les messages d'erreur de STDERR, le tout étant parfaitement synchronisé (chaque message d'erreur était bien positionné juste après la ligne de code ayant généré l'erreur).

    En générant un fichier de log, je souhaite faire la même chose : mêler commentaires + messages erreurs, et rendre plus visible les messages d'errreur en les identifant par un "WARNING".

    La méthode la plus simple serait de faire un die() ou un warn() en commençant le message avec "WARNING" ou autre.
    Mais je serai alors obliger d'en positionner sur chaque ligne de code. Ayant 1500 lignes dans mon script, je suis pas très chaud.

    Je préfèrerai donc pouvoir intercepter les messages d'erreurs automatiquement, ce qui marche avec ... mais avec un synchro qui n'est pas satisfaisant et sans faire précéder les errors d'un "WARNING" !!!

    Je vois pas très bien l'utilité d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print STDERR, "ERROR $!"
    à positionner sur chaque ligne de code, par rapport à un die. Note que je peux en mettre un dans la fonction qui me permet de gérer le print de debugging :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sub printdebug
    {
    print STDERR, "ERROR $!"
    $debug == 1 || print"$_[0]\n";
    }
    ...... mais cela ne me garantit pas de logger TOUTES les erreurs, mais seulement la toute dernière erreur ayant précédé l'utilisation d'un printdebug()

    Je ne sais pas si j'ai été plus clair ???

    FMJ

  8. #8
    Expert éminent
    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
    Points : 8 586
    Points
    8 586
    Par défaut
    Bon, l'autoflush devrait régler ton premier problème (la synchronisation), le deuxième est plus difficile, je te conseille de simplement faire la chose suivante : puisque tu ne peux modifier les warnings standards, modifie tes messages de debugging : j'imagine que tu utilises une fonction perso pour tous tes messages de debug, rajoute simplement une tabulation avant chaque message de debug, ainsi les warnings ressortiront parfaitement.
    --
    Jedai

  9. #9
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut
    Salut Jedai

    En fait ta sugguestion m'a donné une idée pour le second problème.

    J'ai effectivement une fonction printdebug() qui imprime mes commentaires dans un fichier log lorsqu'une condition de debugging est vérifiée.

    En fait, je vais faire précéder chacune de mes lignes de commentaire "perso" d'une signe distinctif (ex : "INFO : ").
    Avant d'imprimer un commentaire, la fonction printdebug() va vérifier que les dernières lignes du fichier de log sont bien précédées de ce signe distinctif.
    Si c'est pas le cas, c'est donc un message d'erreur introduit par le module diagnostic de perl. Et donc la fonction fera précéder ces lignes d'un "ERROR : ".
    Ou bien je ferais la vérif en une fois à la fin du script.

    J'essaye de trouver une minute pour l'implémenter et te dis si c'est satisfaisant.

    Merci

    FMJ

  10. #10
    FMJ
    FMJ est déconnecté
    Membre averti
    Profil pro
    tutu
    Inscrit en
    Octobre 2003
    Messages
    416
    Détails du profil
    Informations personnelles :
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : tutu

    Informations forums :
    Inscription : Octobre 2003
    Messages : 416
    Points : 363
    Points
    363
    Par défaut
    Salut,

    Après expérimentation, la méthode décrite plus haut m'a donné entière satisfaction.

    En complément, j'ai trouvé plusieurs utilitaires / logiciels permettant de faire la compilation de scripts Perl et d'expressions régulières :

    > PerlWiz (Arctan Computer Ventures)
    --> Editeur / compilateur payant - Pas mal !!

    > PerlTkB
    --> Perl Debugger freeware sous PerlTk - J'ai pas tellement creusé le sujet

    > RegEx Coach
    --> Debugger freeware pour expression régulière - ETONNANT !!!!

    > Rx
    --> Un autre Debugger freeware pour expression régulière

    Voilà, en espérant que cela puisse vous être utile.

    FMJ

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

Discussions similaires

  1. [langage] Comment tester si une chaine est vide
    Par |Bio dans le forum Langage
    Réponses: 4
    Dernier message: 04/05/2005, 15h05
  2. Réponses: 3
    Dernier message: 21/01/2004, 08h47
  3. [langage] comment on fait un if(expressioin rationelle)
    Par chtiboss dans le forum Langage
    Réponses: 6
    Dernier message: 05/01/2004, 16h04
  4. [langage] Comment rajouter des champs dans une liste
    Par toto_titi dans le forum Langage
    Réponses: 4
    Dernier message: 28/08/2003, 14h09
  5. [langage] comment créer des fichiers ?
    Par Anonymous dans le forum Langage
    Réponses: 3
    Dernier message: 05/05/2002, 16h33

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