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 :

charger un ficher dans une chaîne (slurp)


Sujet :

Langage Perl

  1. #1
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut charger un ficher dans une chaîne (slurp)
    Bonsoir.

    Je me demandais si les bouts de codes en (1) et (2) sont équivalents, c'est à dire si le séparateur d'enregistrement (input record separator) par défaut ($/) n'est affecté que dans le bloc dans les deux cas.

    (1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $page = do { local $/; <FH> };
     
    # ou de manière plus lisible:
     
    do { 
         local $/; 
         $page = <FH>;
    }
    (2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    do { 
         $/ = undef; 
         $page = <FH>;
    }
    En fait la question porte plutôt sur les clôtures (enclosures). Pour le dire autrement, est-ce le local ou les { } qui font le boulot (de restreindre le changement à une portion de code) ?

    Merci d'avance.

  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
    C'est le local(), comme l'indique son nom... Le deuxième code est incorrect et toutes les lectures par la suite ignoreront les sauts de lignes.
    Par contre le local() agit sur la portée dans lequel il se trouve, il faut donc en créer une artificiellement avec "do {}" pour faire fonctionner cet idiome.

    --
    Jedaï

  3. #3
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Merci.

    C'est la conclusion à laquelle j'étais arrivé avec un test (en rouvrant et relisant le fichier sans plus toucher à $/) sans en être vraiment sûr.

    Car alors pourquoi faut-il des { } autour de local $/; $s = <> ? Pour que local ne s'étende pas à tout le script (ou toute la fonction, si on est dans un sub) ?

  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 iblis Voir le message
    les clôtures (enclosures). Pour le dire autrement, est-ce le local ou les { } qui font le boulot (de restreindre le changement à une portion de code) ?
    Les "clôtures" (closures, et pas enclosures, ou alors on ne parle pas de la même chose) sont encore autre chose, il s'agit de l'idée que quand on crée une subroutine, elle garde un pointeur sur son environnement, et que toute modification d'une variable de son environnement effectué dans la subroutine sera reflétée à l'extérieur :
    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
    # une variable lexicale parfaitement normale :
    my $truc = 0;
     
    # la closure
    sub closure {
      # modification de l'environnement dans lequel closure() a été définie
      $truc++;
    }
     
     
    print "$truc\n"; # "0"
     
    closure();
     
    print "$truc\n"; # "1"
    Ca peut sembler dangereux, mais c'est en fait très pratique pour certaines choses, qui sont parfois accessibles dans d'autres langages sous une forme limité sous le nom de coroutines (le "yield" de Python), par exemple créer des compteurs :
    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
    sub create_counter {
      # cette variable lexicale est différente à chaque invocation de create_counter()
      my $count = shift;
      return sub { return $count++; };
    }
     
    my $from_five = create_counter(5);
    for (;;) {
      my $i = $from_five->();
      print "$i\n";
      last if $i == 10;
    } # affiche 5 6 7 8 9 10
     
    my $from_one = create_counter(1);
     
    print $from_one->(), "\n"; # 1
    print $from_five->(); # 11, n'est pas perturbé
    Ca peut paraître anecdotique ainsi, mais en réalité ça permet des trucs très intéressants, comme de la génération dynamique d'accesseurs dans certaines API, etc...

    Par ailleurs, les closures rendent beaucoup plus puissant le paradigme par callback, en permettant de garder une information partagée entre un certain nombre de callback.

    --
    Jedaï

  5. #5
    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 iblis Voir le message
    Car alors pourquoi faut-il des { } autour de local $/; $s = <> ? Pour que local ne s'étende pas à tout le script (ou toute la fonction, si on est dans un sub) ?
    Le local agit sur la portée dans laquelle il se trouve, donc si tu ne mets pas de { } autour de cet idiôme, il risque de "contaminer" toute la portée dans laquelle tu l'utilises (qui peut éventuellement être le fichier tout entier).

    --
    Jedaï

  6. #6
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Ah d'accord, je comprends mieux, c'est très puissant comme mécanisme, merci.

Discussions similaires

  1. Suppression de mots dans une chaîne
    Par psychomatt dans le forum Langage
    Réponses: 7
    Dernier message: 06/08/2004, 15h34
  2. [String] Remplacement caractères dans une chaîne
    Par Crazyblinkgirl dans le forum Langage
    Réponses: 4
    Dernier message: 19/07/2004, 11h15
  3. Réponses: 4
    Dernier message: 23/06/2004, 09h51
  4. Comment stocker un ficher dans une table postgres
    Par josoft dans le forum Requêtes
    Réponses: 3
    Dernier message: 23/06/2003, 16h41
  5. Comptage de mots dans une chaîne
    Par kikinou dans le forum Pascal
    Réponses: 10
    Dernier message: 01/01/2003, 02h27

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