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 :

ouverture de dossier/fichier dans un sub


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut ouverture de dossier/fichier dans un sub
    Est-il possible d'ouvrir un dossier à l'intérieur d'un sub ?
    J'ai un programme qui fonctionne bien sans sub, mais comme j'ouvre plusieurs fois le fichier, j'aurais voulu ne pas répéter les lignes d'ouverture à chaque fois. Mais ça ne va plus dès que je modifie le programme pour l'alléger...

  2. #2
    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
    Il est tout à fait possible d'ouvrir un dossier ou un fichier dans une sub, et si tu emploie bien les handles lexicaux, tu n'auras pas à te soucier d'influer sur l'extérieur de ta sub...
    Il est également possible de passer un handle de fichier en paramètre, s'il s'agit d'un handle lexical, il suffit de le passer comme n'importe quel scalaire, s'il s'agit d'un GLOB, par exemple FILE, il faut passer \*FILE en paramètre, et à l'intérieur de ta sub tu pourras le traiter comme un paramètre scalaire ordinaire.

    NB : Si tu ouvres un fichier dans ta sub en utilisant des handles lexicaux, il n'est pas visible à l'extérieur (ce qui est nettement préférable), mais tu peux tout à fait le renvoyer avec un return et le récupérer à l'extérieur de ta fonction.

    --
    Jedaï

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jedai
    NB : Si tu ouvres un fichier dans ta sub en utilisant des handles lexicaux, il n'est pas visible à l'extérieur (ce qui est nettement préférable), mais tu peux tout à fait le renvoyer avec un return et le récupérer à l'extérieur de ta fonction.
    un return ? Qu'est-ce ?

    Bon, soyons pragmatique : qu'est-ce qui cloche dans mon programme ?

    Principe du programme : j'ai récupéré des données dans des fichiers log bruts. Chaque fichier résultat (ma source ici) correspond à l'ensemble des établissements pour 1 jour. Je veux maintenant avoir les données d'un établissement sur plusieurs jours.
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    print "Donnez le numero de l'etablissement a traiter :\n";
    my $etab = <STDIN>;
    chomp ($etab);
    my $resultat_etab = "Etab"."$etab"."_resultat_sauv.txt";
     
    # Ouverture du dossier source :
    my $dossier_source = '../Fichiers_resultats_sauv_bruts';
    opendir my($dir_source), $dossier_source 
    	or die "$dossier_source n'existe pas !";
     
    &ouverture_destination;
    print $destination "Date\tEtablissement\tNb total fich\tNb fich modif\n";
    close $destination;
     
     
    # Pour chaque fichier du dossier source :
    while ( my $nom_source = readdir $dir_source ) {
     
    	next if $nom_source =~ m/^\.\.?$/; # Pseudo-dossiers . et ..
     
    	if ( (my $date = $nom_source) =~ s/_resultat_sauv.txt$/\t/ ) {
     
    		# Ouverture du fichier source
    		open my($source), '<', "$dossier_source/$nom_source"  
    			or die "Impossible d'ouvrir votre fichier $nom_source : $!\n ";
     
    		& ouverture_destination;
    		while (my $ligne=<$source>){
     
    			if ($ligne =~ m/^$etab/){
    				print $destination "$date"."$ligne";
    			}
    		}
    	close $source;
    	close $destination;
    	closedir $dir_destination;
    	}
     
    }
    closedir $dir_source;
     
    sub ouverture_destination {
    	# Ouverture du dossier résultats par établissement :
    	my $dossier_etab = '../Fichiers_resultats_par_etab';
    	opendir my($dir_destination), $dossier_etab 
    		or die "$dossier_etab n'existe pas !";
    	# Ouverture du fichier resultat de l'établissement :
    	open my($destination), '>>', "$dossier_etab/$resultat_etab"
    		or die "Impossible d'ouvrir votre fichier $resultat_etab : $!\n ";
    }
    Merci par avance.

  4. #4
    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
    Citation Envoyé par apprenti doc
    un return ? Qu'est-ce ?
    Ce genre de question est inquiétante, elle semble révéler que vous venez d'un langage de programmation extrèmement basique, qui ne possède pas de notion de fonction véritable, mais uniquement de procédure, non plus que de variable locale... Pourrais-tu confirmer que je sache si j'ai bien compris le problème avant de m'embarquer dans de grandes explications ?

    Citation Envoyé par apprenti doc
    Bon, soyons pragmatique : qu'est-ce qui cloche dans mon programme ?
    Plein de choses...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $resultat_etab = "Etab"."$etab"."_resultat_sauv.txt";
    Soit on utilise l'interpolation, soit on utilise la concaténation, mais un mélange des deux comme ici est peu lisible.
    Concaténation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $resultat_etab = 'Etab' . $etab . '_resultat_sauv.txt';
    (si on utilise la concaténation, autant utiliser des simples quotes pour éviter de provoquer une interpolation par erreur)

    Interpolation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $resultat_etab = "Etab${etab}_resultat_sauv.txt";
    Je ne détaillerais pas les erreurs dans le reste du code car elles résultent principalement, sinon uniquement de l'emploi incorrect de cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sub ouverture_destination {
    	# Ouverture du dossier résultats par établissement :
    	my $dossier_etab = '../Fichiers_resultats_par_etab';
    	opendir my($dir_destination), $dossier_etab 
    		or die "$dossier_etab n'existe pas !";
    	# Ouverture du fichier resultat de l'établissement :
    	open my($destination), '>>', "$dossier_etab/$resultat_etab"
    		or die "Impossible d'ouvrir votre fichier $resultat_etab : $!\n ";
    }
    Une variable déclarée par my() est dite locale (ou lexicale), autrement dit elle n'est pas visible (ou utilisable) en dehors de sa "portée", ladite "portée" étant l'ensemble du code présent dans le bloc où l'on a déclaré la variable, après cette déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    # ce code ne voit pas $a
    {
      # ce code ne voit pas $a
      my $a;
      # ce code voit $a
    }
    # ce code ne voit pas $a
    Dans ton programme par exemple, $destination n'est visible que dans la sub ouverture_destination...

    --
    Jedaï

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jedai
    Ce genre de question est inquiétante, elle semble révéler que vous venez d'un langage de programmation extrèmement basique, qui ne possède pas de notion de fonction véritable, mais uniquement de procédure, non plus que de variable locale... Pourrais-tu confirmer que je sache si j'ai bien compris le problème avant de m'embarquer dans de grandes explications ?

    Une variable déclarée par my() est dite locale (ou lexicale), autrement dit elle n'est pas visible (ou utilisable) en dehors de sa "portée", ladite "portée" étant l'ensemble du code présent dans le bloc où l'on a déclaré la variable, après cette déclaration :

    Dans ton programme par exemple, $destination n'est visible que dans la sub ouverture_destination...
    Ok. Grossière erreur. Procédures, fonctions et variables locales n'ont été abordées que dans le dernier des quelques cours que j'ai eus d'initiation à perl. Il faut croire que je ne l'ai pas bien intégré. Je courbe l'échine.
    Mais je ne suis pas informaticien, seulement documentaliste. Je suis déjà bien aise d'automatiser un tant soit peu mes extractions ! Et je dois dire que j'apprends beaucoup dans ce forum.
    Je ne ferme pas la discussion tout de suite : j'essaie d'abord d'assimiler ces derniers conseils et je reviens...

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Bon. Je suis retourné faire un tour du côté du tutoriel "débuter en perl". Mais les explications font souvent référence au C et je n'ai pas su trouver ce que je cherchais.
    A part rajouter return $destination à la fin de ma sub, je ne vois pas ce que je peux faire, et visiblement, ce n'est pas ce qui est attendu...

  7. #7
    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
    Citation Envoyé par apprenti doc
    Bon. Je suis retourné faire un tour du côté du tutoriel "débuter en perl". Mais les explications font souvent référence au C et je n'ai pas su trouver ce que je cherchais.
    A part rajouter return $destination à la fin de ma sub, je ne vois pas ce que je peux faire, et visiblement, ce n'est pas ce qui est attendu...
    Sisi, c'est une bonne idée, faut juste penser à le récupérer derrière

    Regarde :
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    print "Donnez le numero de l'etablissement a traiter :\n";
    my $etab = <STDIN>;
    chomp ($etab);
     
    # Ouverture du dossier source :
    my $src_path = '../Fichiers_resultats_sauv_bruts';
    opendir my($src_dir), $src_path 
      or die "$src_path n'existe pas !\n";
     
    my $out = open_out_by_school( $etab );
    print $out "Date\tEtablissement\tNb total fich\tNb fich modif\n";
     
     
    # Pour chaque fichier du dossier source :
    while ( my $src_name = readdir $src_dir ) {
     
    	next if $src_name =~ m/^\.\.?$/; # Pseudo-dossiers . et ..
     
    	if ( (my $date = $src_name) =~ s/_resultat_sauv.txt$/\t/ ) {
     
    		# Ouverture du fichier source
    		open my($in), '<', "$src_path/$src_name"  
    			or die "Impossible d'ouvrir votre fichier $src_name : $!\n";
    		while (my $line=<$in>){
     
    			if ($line =~ m/^$etab/){
    				print $out "$date$line";
    			}
    		}
    	}
     
    }
    close $out;
    closedir $dir_source;
     
    sub open_out_by_school {
      my $school = shift;
      my $school_path = '../Fichiers_resultats_par_etab';
      my $school_outfile = "Etab${school}_resultat_sauv.txt";
     
      # Ouverture du fichier resultat de l'établissement :
      open my($outfile), '>>', "$school_path/$school_outfile"
        or die "Impossible d'ouvrir votre fichier $school_outfile : $!\n ";
     
      return $outfile;
    }
    A vrai dire ici ta fonction n'est pas des plus utile parce qu'il suffit de l'utiliser une fois (ce n'est une très bonne idée d'ouvrir et de refermer plusieurs fois un même fichier sans raison), mais on peut imaginer qu'elle resserve ailleurs, où tu auras récupéré le nom de l'établissement autrement (c'est l'avantage d'utiliser une fonction qui ne dépend pas du tout de son environnement).

    --
    Jedaï

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Glurp !
    Il faut que je démêle l'anglais du français et le français du perl... Je reviendrai quand j'aurai déchiffré la pierre de Rosette !

  9. #9
    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
    Citation Envoyé par apprenti doc
    Glurp !
    Il faut que je démêle l'anglais du français et le français du perl... Je reviendrai quand j'aurai déchiffré la pierre de Rosette !
    Ouais, désolé j'aime pas les noms de variable en français parce qu'ils sont longs et souvent vague et pas dans la même langue que le reste de Perl. D'un autre côté c'est sûr que vu que le programme fait ses sorties dans la langue de Molière... Les goût et les couleurs ne se discutent pas, si ça te gène trop, un petit coup de replace dans n'importe quel éditeur de texte te corrigera ça en trois coup de cuillère à pot.

    --
    Jedaï

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut 15 jours plus tard...
    Citation Envoyé par apprenti doc
    Glurp !
    Il faut que je démêle l'anglais du français et le français du perl... Je reviendrai quand j'aurai déchiffré la pierre de Rosette !
    Bonjour,
    On va dire que pendant ces 15 jours j'étais en Egypte (j'aurais bien aimé!) à la recherche de la pierre de Rosette. Je ne l'y ai pas trouvée; normal, elle est à Londres. Mais j'y ai appris l'anglais de la rue, et il est aussi bâtard que celui de perl ! Donc, ça va question Anglais, le programme est compréhensible. Ce sont les "mots" spécifiquement perl qui me posent le plus de problèmes.

    Je l'ai testé. Après une très légère modif, il tourne. C'est cool !!!

    J'ai compris que mon programme était trop compliqué, tout simpplement parce que je croyais devoir ouvrir le dossier destination avant de pouvoir ouvrir le fichier destination. Et tout ça à l'intérieur de la boucle (et franchement, aujourd'hui, quelques semaines plus tard, je me demande bien pourquoi)...

    J'ai supprimé la sub puisqu'elle n'était pas d'une grande utilité. Mais pour une autre fois :
    - qu'est-ce que le shift ?
    C'est ce qui correspond au premier des paramètres de la sub, donc ici le seul : $etab ?
    Ou pas du tout !?

    - le return : tu disais "faut juste penser à le récupérer derrière".
    Ici la sub retourne $outfile, mais dans le main on utilise $out. C'est donc que le main utilise la valeur retournée sans avoir besoin de connaître son nom ?
    C'est bien ça ?

  11. #11
    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
    Citation Envoyé par apprenti doc
    J'ai supprimé la sub puisqu'elle n'était pas d'une grande utilité. Mais pour une autre fois :
    - qu'est-ce que le shift ?
    C'est ce qui correspond au premier des paramètres de la sub, donc ici le seul : $etab ?
    Ou pas du tout !?
    En fait shift() est une fonction standard de Perl, qui prend le premier élément d'un tableau et le "sort du tableau" (elle le supprime du tableau et le retourne) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my @nums = (5..10);
    my $five = shift @nums;
    print "$five :: @nums"; # écrit "5 :: 6 7 8 9 10"
    Mais si tu ne lui donne pas explicitement un tableau en paramètre, elle utilise le tableau @ARGV dans le programme principal, ou le tableau @_ dans une fonction. @ARGV contient les arguments du programmes (donnés sur la ligne de commande), @_ contient les arguments de la fonction. C'est assez idiomatique en Perl de récupérer les arguments de la fonction un par un avec shift (quand il y en a un ou deux, ou qu'il y a des traitements à effectuer dessus individuellement, sinon on affecte directement @_ à une liste de scalaires).

    Citation Envoyé par apprenti doc
    - le return : tu disais "faut juste penser à le récupérer derrière".
    Ici la sub retourne $outfile, mais dans le main on utilise $out. C'est donc que le main utilise la valeur retournée sans avoir besoin de connaître son nom ?
    C'est bien ça ?
    Non, c'est parce que j'ai récupéré ce que la sub renvoyait dans $out, à cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $out = open_out_by_school( $etab );
    --
    Jedaï

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jedai
    Non, c'est parce que j'ai récupéré ce que la sub renvoyait dans $out, à cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $out = open_out_by_school( $etab );
    --
    Jedaï
    Oui, mais tu ne cites pas $outfile, c'est ce que je voulais dire...

    En tout cas, merci pour ces précisions.
    Et je ferme la discussion !

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

Discussions similaires

  1. [XL-2003] ouverture d'un fichier dans le même excel
    Par coklin dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 28/09/2009, 11h46
  2. Ouverture d'un fichier dans une nouvelle fenêtre
    Par Bono_BX dans le forum ASP.NET
    Réponses: 2
    Dernier message: 23/04/2009, 08h52
  3. ouverture d'un fichier dans un repertoire
    Par cortex59 dans le forum C++
    Réponses: 2
    Dernier message: 10/02/2009, 11h20
  4. Réponses: 1
    Dernier message: 11/07/2008, 13h26
  5. Ouverture d'un fichier dans windows
    Par stephane.julien dans le forum C#
    Réponses: 2
    Dernier message: 11/01/2008, 11h50

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