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 :

Use of uninitialized value in pattern match (m//)


Sujet :

Langage Perl

  1. #1
    Candidat au Club
    Inscrit en
    Décembre 2006
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Use of uninitialized value in pattern match (m//)
    Bonjour à tous !

    Je débute avec Perl depuis un mois bientôt, et j'aurai besoin de vos lumières quant eu problème explicqué ci dessous :

    J'ai le bout de script suivant :

    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
    if ( open(MOISAvant, "/var/www/folder/st012006.www.site.fr.txt") ) 
    { $PlusieursMois = 1; }
    
    while(<MOISAvant>) {
    		if ( $_ =~ /^(\S+)\s([0-9]+)/ ) 
                    {
    
    			$temp = $2;
    
    			if ( $1 =~ /TotalVisits/ ) { 
    				#print(" TOTAL Visits : $2 \n");
    				$G_visites = $temp; 
    			}
    			if ( $1 =~ /TotalUnique/) { 
    				$G_visitesDiff = $temp; 
    			}
    
    		}
    }
    Ce bout de script me renvoie le message suivant :

    Use of uninitialized value in pattern match (m//) at /var/www/html/awstats/scripts_perl/Xtr.pl line 285, <MOISAvant> line 51.
    Sachant que Xtr.pl est le fichier où se situe ce bout de code, la ligne 51 étant la ligne où je crée le handle de fichier MOISAvant, et la ligne 285 celle où se trouve la dernière accolade en gras dans mon extrait de code ci-contre.

    Quelqu'un voit d'où pourrait provenir mon problème ?

  2. #2
    Membre éprouvé Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Points : 1 118
    Points
    1 118
    Par défaut
    C'est normal : lors de ton 1° test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( $1 =~ /TotalVisits/ ) {
    , les variables $1, $2, $3... sont réinitialisées. Donc au moment de ton 2° test, étant donné que tu n'as rien stocké dans $1 dans le 1° test, $1 est une valeur indéfinie dans ton test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( $1 =~ /TotalUnique/) {
    C'est ce qu'on appelle un effet de bord.
    Toujours se méfier des variables automatiques !
    La solution est de stocker la valeur dans une variable avant de faire les tests :

    Code Perl : 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
    while ( <MOISAvant> ) {
    		if ( $_ =~ /^(\S+)\s([0-9]+)/ ) 
                    {
                            my $champ1 = $1;
    			$temp = $2;
    
    			if ( $champ1  =~ /TotalVisits/ ) { 
    				#print(" TOTAL Visits : $temp  \n");
    				$G_visites = $temp; 
    			}
    			if ( $champ1  =~ /TotalUnique/) { 
    				$G_visitesDiff = $temp; 
    			}
    
    		}
    }

    Quand au warning, il te dit qu'il y a une erreur avec un test m//, car lorsque tu fais appel à une regexp avec //, l'opérateur m (m pour match) est implicite, autrement dit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if ( $champ1  =~ /TotalUnique/) 
    # équivaut à
    if ( $champ1  =~ m/TotalUnique/)

  3. #3
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2006
    Messages : 31
    Points : 34
    Points
    34
    Par défaut
    Bonjour

    J'ai defini une fonction dans un fichier pl avec un appel en dur pour la tester, tout marchait nickel.
    Quand j'ai intégré cette fonction dans mon fichier .pm dans lequel je stocke toutes les sous-fonctions de mon programme principal, j'obtien ce message:

    Use of uninitialized value in pattern match (m//) at sousProgrammeProjetPerl.pm line 366.
    Voila mon code (je travaille sur un fichier GenBank):
    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    # but du sous-programme    : Afficher un champ du paragraphe FEATURE dont le nom est donné en argument (par l'utilisateur)
     
    sub champ_features
    {
     
    	my ($champ, $nom_fichier) = @_;
    	my @recup = affiche_tout($nom_fichier);  #fonction qui recupere le contenu du fichier (fonctionne bien)
    	my @feature = ();
    	my @result_recherche = ();
     
      # =================================
      # Verification de l'existence de ce champ dans le fichier
      # =================================
    	my $i=0;   # compteur servant a reperer la presence du mot dans le fichier
     
    	foreach my $ligne (@recup)
           {
    		if ($ligne =~ /^\s*$champ\s.*$/i)     # verifie que la ligne commence par le mot cle precede de 0 ou plusieurs espaces
                     {
    			$i++;
    		 }
    	}
     
    	# =================================
    	# Si le champ n'existe pas:
    	# =================================
    	if ($i==0)
            {
    		print "\nLe champ '$champ' n'existe pas\n\n";
    	}
     
      # =======================================================================================================
    # si il existe, on va recuperer tout son contenu dans une variable sur laquelle on va ensuite travailler
      # =======================================================================================================	
    	else 
           {
              print "\nLe champ \"$champ\" existe et est present $i fois dans le fichier\n\n";
    	 my $j;
    	 my $nblignes;
     
    	for ($i=0; $i<@recup; $i++)
    		{
    		if ($recup[$i]=~ /^FEATURES/i) 		#récupération ligne ou FEATURES est présent
    		{
      			$feature[0] = $recup[$i];
      			$nblignes = 0;
     
      			for($j=$i+1; $j<@recup; $j++) 
                               { $nblignes ++;
                                  if ($recup[$j] =~ /^(\w+) +(.*?) *$/i)    
          			   {
          			     print "nombre de lignes du champ FEATURES: $nblignes\n\n";
                           }
                      else          # affiche les lignes suivantes si il y en a plusieurs 
                     {
                        $feature[$nblignes] = "$recup[$j]"; 
                     }                    
        	    }
            }
        }
     
      # =======================================================================================================
    # on va recuperer toutes les lignes concernant le champ (rq: le champ peut apparaitre plusieurs fois)
      # =======================================================================================================	
     
        my @result_recherche = ();   # sert a stocker dans un tableau les lignes (utile si le mot cle est present plusieurs fois dans FEATURE)
        $nblignes =0;
     
        print "champ = $champ\n\n";
        print "feature0 = $feature[0]\n\n";
    		for ($i=0; $i<@feature; $i++)
    		{
                       if ($feature[$i] =~ /^\s*$champ/i) 	  # verifie que la ligne commence par le mot cle precede de 0 ou plusieurs espaces	
      			{
      			  $result_recherche[$nblignes] = $feature[$i];
      			  $nblignes++;
     
                              for($j=$i+1; $j<@feature; $j++) 
                                { 
                                   if ($feature[$j]=~ /^\s{20}.*$/i)    # affiche les lignes suivantes si il y en a plusieurs
        			      {
        			         $result_recherche[$nblignes] = $feature[$j];
        			         $nblignes++;
                                  }
                                  else {last;}      # force a quitter la boucle "for" et retourne dans la boucle "if" precedente
      			  }
      		  }   
         } 
         return @result_recherche;
      }
     
    }
    D'apres le message, l'erreur se situe là (au niveau de la derniere ligne):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    print "champ = $champ\n\n";
        print "feature0 = $feature[0]\n\n";
    		for ($i=0; $i<@feature; $i++)
    		{
                       if ($feature[$i] =~ /^\s*$champ/i)
    Les print servent a rien, je les ai mis pour tester que les variables possedaient bien la bonne valeur

    Le code est un peu long, je suis désolé.

    Ce qui est bizarre c'est que la fonction toute seule fonctionne bien et sans message d'erreur, mais dans le fichier.pm rien ne va plus...

  4. #4
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    En dehors du fait que tu as d'énormes progrès à faire en matière d'indentation, je trouve la façon que tu as de te compliquer la vie particulièrement effrayante.

    J'essaie de comprendre ce que tu cherches à faire, mais ça n'est pas clair du tout. Il faudrait que tu nous montre un fichier type, mais si j'ai bien compris, dans ton fichier, toutes les lignes commencent par des blancs (espaces, tabulations ou autres) sauf celles qui indiquent les noms de paragraphes, c'est bien ça ? Et tu veux récuperer les lignes commençant par des espaces suivis de la valeur de $champ et se trouvant dans le paragraphe FEATURES, c'est ça ?
    Si c'est bien ça, il y a beaucoup plus simple que ton usine à gaz. Je crois que tu as encore du mal à raisonner en Perl. Tu viens du C, non ? Tu me donnes l'impression de raisonner en C (ç'a été mon cas, au début). Ton problème est de ceux pour lesquel Perl a été spécifiquement conçu dès le départ, et qu'on peut résoudre en peu de lignes avec un peu de magie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sub champ_features
    {
      my ($champ, $nom_fichier) = @_;
      my @recup = affiche_tout($nom_fichier);  #fonction qui recupere le contenu du fichier (fonctionne bien)
    #récupération du paragraphe FEATURES
    #voir plus bas pour l'opérateur ..
      my @feature = grep {/^FEATURES/ .. /^\S/} @recup;
      grep{/^\s*$champ/} @feature;
    }
    Pour t'expliquer en quoi consiste l'opérateur .. que j'ai utilisé dans le premier grep, je te renvoie à mon dernier post dans ce thread (qui renvoie à un article en anglais en cas de besoin).

    Même si je me suis trompé sur tes intentions exactes, je te recommande de te pencher sur grep (voir perldoc perlfunc), ça devrait te servir de toute façon.

    Bon, ça c'était pour le principe. En ce qui concerne ton problème spécifique actuel, je ne sais pas trop.

    EDIT : ah, je viens de réaliser que je n'ai pas tenu compte de la regex /^\s{20}.*$/i, dont tu n'expliques absolument pas le rôle. Il faut vraiment que tu nous expliques comment ton fichier est foutu.

  5. #5
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2006
    Messages : 31
    Points : 34
    Points
    34
    Par défaut
    Bonsoir

    Pour les indentations c'est en mettant dans la balise de code que tout a bougé sinon elles sont bonnes dans mon script au depart.

    Comme vous le dites, j'ai tendance à me compliquer et je débute en perl donc mes lignes de codes tiennent plus de la bidouille qu'autre chose (c'est de l'artisanal )

    Pour voir a quoi ressemble un fichier GenBank, je mets une image a la suite:


    Il faut savoir que tous les fichiers de ce type ont un "formatage" identique.

    le /^\s{20}.*$/i sert a récupérer les lignes suivant le champ cherché car elles auront toutes un décalage de 20 caractères. Lorsqu'on n'a plus ce décalage, c'est qu'on est arrivé au champ suivant.

    Sinon mon code bien que compliqué n'est pas faux puisque pris individuellement il génère une réponse sans erreur. C'est une fois que je l'ai rajouté dans le .pm que j'ai eu ce message d'erreur.

    Dans une fonction tout seul (en cherchant le champ "sts"):


    Dans le programme (en cherchant toujours "sts")


    Dans un 1er temps j'aimerai savoir ce qui cloche avant d'optimiser comme vous me le suggérez a juste titre (l'utilisation de grep a l'air bien plus pratique et rapide..)

Discussions similaires

  1. Use of uninitialized value in pattern match(m//)
    Par hayaet dans le forum Langage
    Réponses: 1
    Dernier message: 08/10/2007, 12h45
  2. Use of uninitialized value
    Par Djahny dans le forum Langage
    Réponses: 6
    Dernier message: 27/05/2007, 00h49
  3. Use of uninitialized value in string ne at
    Par Gad29 dans le forum Programmation et administration système
    Réponses: 4
    Dernier message: 09/05/2007, 14h49
  4. [USE STRICT] uninitialized value in print ...
    Par pop_up dans le forum Langage
    Réponses: 4
    Dernier message: 24/04/2006, 15h18
  5. [langage] Use of uninitialized value
    Par Batou dans le forum Langage
    Réponses: 2
    Dernier message: 21/02/2005, 11h28

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