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 :

eval() et formats...


Sujet :

Langage Perl

  1. #1
    Invité
    Invité(e)
    Par défaut eval() et formats...
    Bonjour à tous,

    Pour mon premier post sur ce forum, j'ai un probleme... (je me rattraperait promis!)

    Je suis en train de faire un petit logiciel qui affiche une liste de flux radio avec ncurses, les informations viennent d'un fichier XML, et lors de l'affichage de ma liste, je veux pouvoir changer l' ordre des colonnes et les informations affichées...

    Je me suis dit que pour faire ca, je pouvait faire un format, mais il faut qu'il soit dynamique (en fait, il change juste au demarage), donc, j'ai un fonction qui genere un format en fonction d'une chaine :
    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
     
    #!/usr/bin/perl -w
     
    #
    # Nouvelle version pour la generation de formats...
    #
    use strict;
     
    package Format;
     
    # definition des variables
    %Format::fields = (
       '$server_name'  => 20,
       '$listen_url'   => 20,
       '$server_type'  => 4,
       '$bitrate'      => 4,
       '$channels'     => 2,
       '$samplerate'   => 5,
       '$genre'        => 10,
       '$current_song' => 20
    );
     
    sub generate {
       my $buffer = shift;
       my $format_name = shift;
       my $format;
       my $values;
     
       # On commence par remplacer les alias
       $buffer =~ s/\\t/\\\{4\}/g;
     
       while ($buffer ne "") {
          $format .= ' 'x$1 if $buffer =~ s/^\\\{(\d+)\}//;
          $format .= $1     if $buffer =~ s/^(.*?)([\\\{(\d+)\}|\$\w+])/$2/;
          if ($buffer =~ s/^(\$\w+)//) {
             my $var = $1;
             $values .= $var.',';
             $format .= '@'.'<'x$Format::fields{$var};
          }
       }
       chop $values;
       return 'format '.$format_name."=\n".$format."\n".$values."\n.\n";
    }
     
    1;
    __END__
    Bon, c'est peut etre pas super optimisé, mais ca marche...

    ensuite, losque que je veux faire ma boucle qui affiche le contenu de l'XML, je fait ceci :
    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
     
    #!/usr/bin/perl -w
     
    use strict;
    use XML::DOM;
     
    use Format;
     
    my $test = '$server_name\t\t$genre\t$server_type';
    my $format = Format::generate($test, 'STDOUT');
    #eval ($format);
     
    my $file = '/home/keymaker/Projects/radio-daemon/perl/data.tmp';
    my $parser = XML::DOM::Parser->new();
     
    my $doc = $parser->parsefile($file);
     
    foreach my $flux ($doc->getElementsByTagName('entry')) {
       my $server_name = $flux->getElementsByTagName('server_name')
                            ->item(0)
                            ->getFirstChild->getNodeValue;
     
       my $genre = $flux->getElementsByTagName('genre')
                            ->item(0)
                            ->getFirstChild->getNodeValue;
       my $server_type = $flux->getElementsByTagName('server_type')
                            ->item(0)
                            ->getFirstChild->getNodeValue;
       eval ($format);
       write;
    }
     
    __END__
    et le probleme est ici, si je fait mon eval, au debut du code, telle qu'il est mis en commentaire, il ne veux pas afficher la liste...
    message d'erreur :
    Can't use string ("server_name") as a SCALAR ref while "strict refs" in use at (eval 56) line 3.
    et si je le met la ou il est decomenté, c'est à dire juste avant le write, j'ai le droit à un warning à chaque iteration :
    Format STDOUT redefined at (eval 57) line 1.
    Comment faire ?? je tien à precisé, que je suis ouvert à toutes suggestions concernant ce code (je suis en train d'apprendre le perl, et si mon code n'est pas très rapide ou que l'oon peut faire autrement (surement), mais surtotu plsu rapide, je suis ouvert à toute proposition...)

    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
    format a un petit problème avec les variables locales s'il n'est pas dans la même portée, aussi il faut prédéclarer les variables $server_name, etc..

    --
    Jedaï

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Jedai
    format a un petit problème avec les variables locales s'il n'est pas dans la même portée, aussi il faut prédéclarer les variables $server_name, etc..
    donc si j'ai bien compris, je fait un my $vars, dans le eval ?

  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
    Non, tu réécris ton code comme ça :
    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
     
    #!/usr/bin/perl
     
    use strict;
    use XML::DOM;
     
    use Format;
     
    my ($server_name, $genre, $server_type);
    my $test = '$server_name\t\t$genre\t$server_type';
    my $format = Format::generate($test, 'STDOUT');
    eval ($format);
     
    my $file = 'data.tmp';
    my $parser = XML::DOM::Parser->new();
     
    my $doc = $parser->parsefile($file);
     
    foreach my $flux ($doc->getElementsByTagName('entry')) {
       $server_name = $flux->getElementsByTagName('server_name')
                            ->item(0)
                            ->getFirstChild->getNodeValue;
     
       $genre = $flux->getElementsByTagName('genre')
                            ->item(0)
                            ->getFirstChild->getNodeValue;
       $server_type = $flux->getElementsByTagName('server_type')
                            ->item(0)
                            ->getFirstChild->getNodeValue;
       #~ eval ($format);
       write;
    }
     
    __END__
    Tu devrais aussi déclarer %fields en local, ça ne t'apporte rien de le déclarer en global comme tu le fais (et même dans ce cas, tu devrais utiliser "our").

    --
    Jedaï

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Jedai
    Tu devrais aussi déclarer %fields en local, ça ne t'apporte rien de le déclarer en global comme tu le fais (et même dans ce cas, tu devrais utiliser "our").
    Merci pour le coup des formats...

    Pourquoi ne pas declarer en global ?? je me suis dit que ca me servirait peut etre... ca change quelque chose ??

    bon, je vais aller me docuimenter un peu plus sur les packages aussi...

    edit : après test, ca ne marche toujours pas... il me fait un
    Use of uninitialized value in formline at (eval 56) line 3.

  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
    C'est bizarre... Tu es sûr que tu as fait un copier-coller exact de mon code ? Tu n'as pas oublié d'enlever les my() à l'intérieur de la boucle par exemple ?

    Par ailleurs, je te conseille d'utiliser plutôt cette légère modification de Format.pm :
    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
     
    #!/usr/bin/perl -w
     
    #
    # Nouvelle version pour la generation de formats...
    #
    use strict;
     
    package Format;
     
    # definition des variables
    our %fields = (
       '$server_name'  => 20,
       '$listen_url'   => 20,
       '$server_type'  => 4,
       '$bitrate'      => 4,
       '$channels'     => 2,
       '$samplerate'   => 5,
       '$genre'        => 10,
       '$current_song' => 20
    );
     
    sub generate {
       my $buffer = shift;
       my $format_name = shift;
       my $format;
       my $values;
     
       # On commence par remplacer les alias
       $buffer =~ s/\\t/\\\{4\}/g;
     
       while ($buffer ne "") {
          $format .= ' 'x$1 if $buffer =~ s/^\\\{(\d+)\}//;
          $format .= $1     if $buffer =~ s/^(.*?)([\\\{(\d+)\}|\$\w+])/$2/;
          if ($buffer =~ s/^(\$\w+)//) {
             my $var = $1;
             $values .= $var.',';
             $format .= '@'.'<'x $fields{$var};
          }
       }
       chop $values;
       return 'format '.$format_name."=\n".$format."\n".$values."\n.\n";
    }
     
    1;
    __END__
    Si tu pouvais me donner un exemple du XML que tu traites, ça pourrait m'aider aussi (si c'est confidentiel, tu peux mettre des valeurs bidons, c'est pas un problème).

    --
    Jedaï

  7. #7
    Invité
    Invité(e)
    Par défaut
    l'xml ?? oh non, c'est vraiment pas confidentiel...

    dispo sur : http://dir.xiph.org/yp.xml

    bon, j'ai du faire quelques erreurs pour mes my()... je vais revoir tout ca...

    effectivement, ca marche tout bien maintenant... Je vais pouvoir coder la version avec toutes les variables...

Discussions similaires

  1. [VB6] [Flexgrid] Format d'affichage des numériques
    Par yansolo dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 19/10/2002, 21h00
  2. convertir un nom long (win32) en format dos (8+3)
    Par kylekiller dans le forum Langage
    Réponses: 2
    Dernier message: 30/08/2002, 13h34
  3. Format d'un exe pour DOS et pour Windows
    Par Alfhiger dans le forum Assembleur
    Réponses: 4
    Dernier message: 12/06/2002, 11h57
  4. lire une image au format RAW
    Par Anonymous dans le forum OpenGL
    Réponses: 5
    Dernier message: 20/05/2002, 00h11
  5. Réponses: 3
    Dernier message: 06/05/2002, 18h24

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