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 :

affectation d'une valeur ou d'une autre


Sujet :

Langage Perl

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 87
    Points : 92
    Points
    92
    Par défaut affectation d'une valeur ou d'une autre
    Bonjour,

    dans un fichier de config, j'ai une variable globale du style:


    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
    Set(%mailParPlaque, (
    #Mainteneurs
    '14' => {
                    'CHARENTES MARITIMES (17)' => ['mnt-cha','rol-cha'],
                    'BACKBONE' => ['mnt-idf','rol-idf'],
                    'HAUT-RHIN (68)' => ['mnt-hrh','rol-hrh'],
                    'TOURS(37)' => ['mnt-tou','rol-tou'],
                    'VIENNE (86)' => ['mnt-vie','rol-vie'],
                    'regexp' => '^(mnt|rol)'
            },
    #blabla
    '15' => {
                    'CHARENTES MARITIMES (17)' => [blabla],
                    'BACKBONE' => [blabla],
                    'HAUT-RHIN (68)' => [blabla],
                    'TOURS(37)' => [blabla],
                    'VIENNE (86)' => [blabla],
                    'regexp' => '^blabla'
            }
    ));

    affectation d'une variable:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my @people = undef; #people to add
    @people = @{$mailParPlaque{$id_queue}{$plaque}};
    ça, ca fonctionne bien
    mais si par exemple ma variable $plaque est VENDEE (85), ca me génère une erreur. (la queue ne peut pas ne pas exister)

    du coup j'aimerais faire un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @people = @{$mailParPlaque{$id_queue}{$plaque}} // "nada";
    le souci étant que @people n'est pas un scalaire
    du coup ca me renvoie:
    @people
    $VAR1 = 2;

    Avez-vous une idée de comment définir @people si la variable globale %mailParPlaque ne contient pas $plaque?

    Merci d'avance,

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Pas sûr d'avoir bien compris ce que tu veux faire, mais peut-être que cela suffirait à résoudre ton problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @people = @{$mailParPlaque{$id_queue}{$plaque}} // ("nada");

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 87
    Points : 92
    Points
    92
    Par défaut
    Hello,

    en gros, je veux que si la première valeur n'existe pas, la valeur "nada" soit affectée.

    l'opérateur // ne fonctionne pas sur des listes, j'avais déjà essayé ton idée

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je ne pense pas que ceci fonctionne, Lolo, car le premier déréférencement en @{} échouera du fait que la clé "Vendée (85)" n'existe pas, et retourne donc undef AVANT le dérérencement en tableau. Mais en fait, après test, ce n'est pas ce qui gêne (il semble que déréférencer en tableau la valeur undef retourne un tableau vide ou undef). Le problème vient du fait que l'opérateur // est un opérateur scalaire, et qu'il prend comme opérande (et retourne comme résultat) des scalaires. Donc si la clé existe, il retourne la taille du tableau, sinon, "nada".

    Du coup, je verrais plutôt ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    @people = exists $mailParPlaque{$id_queue}{$plaque} ? @{$mailParPlaque{$id_queue}{$plaque}} : ("nada");
    (on peut éviter de répéter la référence du tableau en passant par une variable my intermédiaire).
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 87
    Points : 92
    Points
    92
    Par défaut
    Yes ca fonctionne!
    Merci beaucoup!!

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Yes, en effet, je n'ai jamais utilisé l'opérateur // (je suis scotché avec des versions trop anciennes de Perl), je me disais juste que ça pouvait peut-être marcher comme cela.

    Et je me suis fait déjà avoir plusieurs fois avec l'auto-vivification d’éléments de hash n'existant pas mais devenus définis par le simple fait de tester leur existence (franchement, pour moi, c'est un bug de Perl), je pense que l'utilisation de la fonction exists dans un opérateur ternaire proposée par Philou est sans doute une meilleure solution, bien plus sûre.

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    L'auto-vivification est une fonctionnalité de perl (pas un bug) dont l'usage souvent non désiré du programmeur, génère des bugs dans l'application.

    Cela dit, je viens de vérifier que même en utilisant exists, l'auto-vivification est active, ce qui m'interpelle quelque peu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    use strict;
    use warnings;
    my %h;
    if (exists $h{a}->{b}) {
      say "Auto-vivification with exists";
    }
    if (defined $h{A}{B}) {
      say "Auto-vivication with defined";
    }
    use Data::Dumper;
    print Data::Dumper->Dump([\%h], [qw(*h)])
    Pour information, après installation du module CPAN autovivification, il est possible de désactiver cette fonctionnalité en ajoutant une ligne :
    Dommage que ce module ne soit pas dans le Core.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    J'avais récemment un traitement qui faisait ce qui suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (exists $liste{$segment}{$presta}) { # ... }
    Le simple fait de faire le test créait l'enregistrement dans le hash, ce qui fait que lors du test suivant avec les mêmes valeurs, le "if" renvoyait vrai et le code gouverné par le "if" s'exécutait alors qu'il n'aurait pas dû. Pour moi, c'est un bug dans le sens que l'auto-vivification ne devrait pas se faire sur un simple test d'existence.

    Larry Wall, Tom Christiansen et Jon Orwant écrivent à ce sujet (3ème édition de Programmation en perl", p. 232 de l'édition française):

    "(Le fait que cela définisse (...) dans un contexte de rvalue devrait être considéré comme un bogue. Nous corrigerons peut-être cela un jour.)"

    A ce jour, ce n'est à ma connaissance toujours pas corrigé.

    Dans mon cas, en remplaçant le code ci-dessus par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (defined $liste{$segment}{$presta}) { # ... }
    j'ai supprimé le problème, parce que même après avoir testé la simple existence, le hash existe pour ce couple de valeurs, mais sa valeur n'est pas définie. C'est un peu dommage parce que dans un tel contexte, la fonction exists est un peu plus rapide que la fonction defined (pas très grave quand même).

  9. #9
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je suis d'accord pour le cas de la vérification d'existence.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 05/02/2015, 14h47
  2. Réponses: 8
    Dernier message: 05/04/2011, 08h06
  3. Réponses: 82
    Dernier message: 05/02/2011, 14h34
  4. Réponses: 10
    Dernier message: 30/11/2006, 23h06
  5. copie d'une table Y d'une base A vers une table X d'une base
    Par moneyboss dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/08/2005, 21h24

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