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 :

Passage de tableaux associatifs en paramètre de sub [Débutant(e)]


Sujet :

Langage Perl

  1. #1
    Inscrit
    Profil pro
    aaaaa
    Inscrit en
    Novembre 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : aaaaa

    Informations forums :
    Inscription : Novembre 2006
    Messages : 178
    Points : 70
    Points
    70
    Par défaut Passage de tableaux associatifs en paramètre de sub
    Bonjour,

    J'ai tout juste débuté en Perl et je bute sur des problèmes d'utilisation et de transfert de tableaux associatifs entre les différentes fonctions de mon petit programme.

    L'objectif de ce programme est de calculer le nom de champ le plus long d'une table SQL.

    Le process du code est le suivant :
    - Je définis dans %sqlv_tables la liste de mes champs avec les alias des tables utilisées.
    - Je boucle sur les tables (CONTRAT et ETABLISSEMENT)
    - Pour chaque table j'appelle la fonction getMaxFieldNameLength qui, elle, boucle sur chaque alias de la table (en l'occurrence, un seul par table ici), puis sur chaque champ pour déterminer lequel a le nom le plus long :

    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
    use strict;
    use Data::Dumper;
     
    our %sqlv_tables = ('CONTRAT'=>
    					('c'=>
    					 ('numeroContrat'=>'OK',
    					  'dateContrat'=>'OK')),
    					'ETABLISSEMENT'=>
    					 ('e'=>
    					  ('codeEtablissement'=>'OK')));
     
     
    print "\n Tables : \n\n";
     
    foreach my $tableName (keys (%sqlv_tables)) {
    	print $tableName." : ";
    	print Dumper $sqlv_tables{$tableName};
    	my $maxFieldNameLength = getMaxFieldNameLength($sqlv_tables{$tableName});
    	print "$tableName : nom de champ le plus long = ".$maxFieldNameLength;
    	print "\n\n\n\n\n";
    }
     
    print "\n";
     
     
    sub getMaxFieldNameLength {
    	my %tableAliases=shift;
    	print "\n=======\n";
    	print Dumper \%tableAliases;
    	print "\n=======\n";
    	my $maxLength = 0;
    	foreach my $tableAlias (keys (%tableAliases)) {
    		print "Alias table = ".$tableAlias."\n";
    		print Dumper $tableAliases{$tableAlias};
    		foreach my $field (keys {$tableAliases{$tableAlias}}) {
    			$maxLength = length($field) if ($maxLength lt length($field));
    			print $field;
    		}
    	}
    	return $maxLength;
    }

    Le résultat de cette exécution est le 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
    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
     Tables :
     
    ETABLISSEMENT : $VAR1 = 'e';
     
    =======
    $VAR1 = {
              'e' => undef
            };
     
    =======
    Alias table = e
    $VAR1 = undef;
    ETABLISSEMENT : nom de champ le plus long = 0
     
     
     
     
    codeEtablissement : $VAR1 = 'OK';
     
    =======
    $VAR1 = {
              'OK' => undef
            };
     
    =======
    Alias table = OK
    $VAR1 = undef;
    codeEtablissement : nom de champ le plus long = 0
     
     
     
     
    CONTRAT : $VAR1 = 'c';
     
    =======
    $VAR1 = {
              'c' => undef
            };
     
    =======
    Alias table = c
    $VAR1 = undef;
    CONTRAT : nom de champ le plus long = 0
     
     
     
     
    dateContrat : $VAR1 = 'OK';
     
    =======
    $VAR1 = {
              'OK' => undef
            };
     
    =======
    Alias table = OK
    $VAR1 = undef;
    dateContrat : nom de champ le plus long = 0
     
     
     
     
    numeroContrat : $VAR1 = 'OK';
     
    =======
    $VAR1 = {
              'OK' => undef
            };
     
    =======
    Alias table = OK
    $VAR1 = undef;
    numeroContrat : nom de champ le plus long = 0
    (c'est un peu verbeux !)

    Il y a plusieurs choses que je ne comprends pas :
    - J'ai demandé à boucler sur les clés de %sqlv_tables. Pour moi, ça se limite à CONTRAT et ETABLISSEMENT, pourtant l'exécution boucle aussi sur numeroContrat, dateContrat et codeEtablissement, pourquoi ?
    - Lorsque je passe par exemple $sqlv_tables{'ETABLISSEMENT'} à ma fonction et que j'affiche son contenu, ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $VAR1 = {
              'e' => undef
    };
    Pourquoi ? Pourquoi n'arrive-t-il pas à trouver le contenu de ce tableau au niveau de la clé "e" ?


    Merci pour votre indulgence ! Je pense que Perl est un langage intéressant mais je débute...

  2. #2
    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
    En premier lieu, tu as mal déclaré ta variable sqlv_tables

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    our %sqlv_tables = ('CONTRAT'=>
    					('c'=>
    					 ('numeroContrat'=>'OK',
    					  'dateContrat'=>'OK')),
    					'ETABLISSEMENT'=>
    					 ('e'=>
    					  ('codeEtablissement'=>'OK')));
    Il faut que tu saches en préambule que perl ne gère pas les tableaux (ou hash) de tableaux (ou de hash). Les tableaux, et les hash, ne peuvent être composés que de scalaires (données à une dimension).
    En revanche, pour imbriquer des tableaux (ce que tu souhaites faire), tu peux utiliser des "références" de tableau (ou de hash), qui eux, sont des scalaires (c'est en quelque sorte des pointeurs).

    Pour définir une référence de tableau (ou de hash) de manière littérale, il faut alors utiliser des [ ] (respectivement des { }) en lieu est place des parenthèses.

    Dans ton exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    our %sqlv_tables = ('CONTRAT'=>
    					 { 'c'=>
    					  {'numeroContrat'=>'OK',
    					  'dateContrat'=>'OK',
                                              }
    					 },
    					 'ETABLISSEMENT'=>
    					 { 'e'=>
    					  { 'codeEtablissement'=>'OK',
                                              }
                                             });
    Ensuite, lorsque tu appelles la fonction getMaxFieldNameLength de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getMaxFieldNameLength($sqlv_tables{$tableName})
    tu passes en paramètre l'élément $sqlv_tables{$tableName}, qui comme l'indique le sigil initial $, est un scalaire. C'est une référence qui est passé en paramètre.

    Donc dans ta fonction, soit :
    - tu utilises la référence et dans ce cas, tu procèdes ainsi :
    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 getMaxFieldNameLength {
    	my $tableAliases_ref = shift;
     
    	print "\n=======\n";
    	print Dumper $tableAliases_ref;
    	print "\n=======\n";
    	my $maxLength = 0;
    	foreach my $tableAlias (keys (%$tableAliases_ref)) {
    		print "Alias table = ".$tableAlias."\n";
    		print Dumper $tableAliases->{$tableAlias};
    		foreach my $field (keys {$tableAliases->{$tableAlias}}) {
    			$maxLength = length($field) if ($maxLength lt length($field));
    			print $field;
    		}
    	}
    	return $maxLength;
    }
    - soit tu passes le hash complet en paramètre, et dans ce cas, tu procèdes ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	my $maxFieldNameLength = getMaxFieldNameLength($sqlv_tables{$tableName});
     
    ...
     
    sub getMaxFieldNameLength {
    	my %tableAliases=@_;
     
    ...
    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

  3. #3
    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
    Tu as défini un hash de hash. Le hash %sqlv_tables n'a que deux clés, CONTRAT et ETABLISSEMENT. Le reste des données est dans les sous-hash.

    La définition des hash internes n'est pas bonne. Essaie plutôt ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    our %sqlv_tables = ('CONTRAT'=>
    					{'c'=>
    					 {'numeroContrat'=>'OK',
    					  'dateContrat'=>'OK'}},
    					'ETABLISSEMENT'=>
    					 {'e'=>
    					  ('codeEtablissement'=>'OK'}});
    EDIT: grillé par Philou.

  4. #4
    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
    Tu as défini un hash de hash. Le hash %sqlv_tables n'a que deux clés, CONTRAT et ETABLISSEMENT. Le reste des données est dans les sous-hash.

    La définition des hash internes n'est pas bonne. Essaie plutôt comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    our %sqlv_tables = ('CONTRAT'=>
    					{'c'=>
    					 {'numeroContrat'=>'OK',
    					  'dateContrat'=>'OK'}},
    					'ETABLISSEMENT'=>
    					 {'e'=>
    					  ('codeEtablissement'=>'OK'}});
    Ce qui te permettra d'accéder, par exemple, à $sqlv_tables{CONTRAT}{c}{numeroContrat}, qui te renverra 'OK'.

  5. #5
    Inscrit
    Profil pro
    aaaaa
    Inscrit en
    Novembre 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : aaaaa

    Informations forums :
    Inscription : Novembre 2006
    Messages : 178
    Points : 70
    Points
    70
    Par défaut
    D'accord je vois. Ca marche mieux effectivement (@Philou67430 : Tu avais juste laissé des $tableAliases au lieu de $tableAliases_ref, j'ai corrigé de moi-même) Merci à vous deux pour les explications détaillées !

    Du coup, plusieurs questions de rab :
    • Puisque les accolades permettent de délimiter les données du tableau associatif %sqlv_tables, pourquoi ce sont des parenthèses au tout début et à la toute fin de cette déclaration ?
    • Dans le cas où j'utilise
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      sub getMaxFieldNameLength {
      	my %tableAliases=@_;
      	...
      }
      ce que signifie "@_", c'est "mets dans %tableAliases la variable associée à la référence passée en argument", c'est ça ? Est-ce que c'est la même chose que le code suivant ?
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      sub getMaxFieldNameLength {
      	my $tableAliases_ref = shift;
      	my %tableAlises = %$tableAliases_ref;
      }
    • Quand on fait :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      $tableAliases_ref->{'e'}
      je ne comprends pas trop pourquoi on met "$" en non "%" devant tableAliases, puisque ce dernier n'est pas un scalaire. Est-ce que le $ fait référence à ce qu'on récupère (donnée qui est dans %tableAliases à l'indice "e") plutôt qu'à l'endroit où on va le chercher (c'est-à-dire %tableAliases lui-même) ?


    Mon dernier point n'est pas très clair. Je crois que mon incompréhension principale est liée au fait que pour une même variable, on ne met pas toujours le même sigil...

  6. #6
    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
    Le sigil $ sert toujours à identifier un scalaire (une valeur unique).
    Le sigil @ sert toujours à identifier un tableau dans son ensemble.
    Le sigil % sert toujours à identifier un hash dans son ensemble.

    Il faut que tu saches que chaque opérateur et fonction peut avoir un fonctionnement relatif au contexte "scalaire" ou "tableau" (dans ce cas, un hash est aussi considéré comme un tableau composé d'une liste de clé/valeur à la file). Ainsi, affecter un tableau dans un scalaire, comme ceci :
    c'est comme écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $size = scalar(@table)
    Or, forcer un tableau en scalaire, c'est récupérer sa taille.

    Maintenant, je réponds en détail à tes questions (dans le message suivant)
    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

  7. #7
    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
    Citation Envoyé par brunoperel Voir le message
    D'accord je vois. Ca marche mieux effectivement
    Puisque les accolades permettent de délimiter les données du tableau associatif %sqlv_tables, pourquoi ce sont des parenthèses au tout début et à la toute fin de cette déclaration ?
    Parce que les accolades servent à délimiter les données d'une référence à un tableau associatif anonyme. les parenthèses, elles, délimitent une liste dont les éléments seront passés à ton tableau associatif %sqlv_tables. Soit dit en passant, j'aimerais savoir pourquoi tu déclares ce dernier avec our. Sans raison spécifique, c'est une mauvaise habitude.

    Dans le cas où j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    sub getMaxFieldNameLength {
    	my %tableAliases=@_;
    	...
    }
    ce que signifie "@_", c'est "mets dans %tableAliases la variable associée à la référence passée en argument", c'est ça ?
    Non, tu passes le contenu du tableau associatif passé en argument directement (pas par référence donc) à la variable %tableAliases. Ce qui répond en partie à ta question suivante :
    Est-ce que c'est la même chose que le code suivant ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    sub getMaxFieldNameLength {
    	my $tableAliases_ref = shift;
    	my %tableAlises = %$tableAliases_ref;
    }
    Non, dans ce cas c'est une référence qui est passée en argument. Dans le cadre de ton problème, ça n'est pas vraiment utile de procéder ainsi : tu ne cherches pas à modifier directement les données du tableau associatif d'origine, et le tableau associatif est le seul argument de ton sous-programme.

    Quand on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $tableAliases_ref->{'e'}
    je ne comprends pas trop pourquoi on met "$" en non "%" devant tableAliases, puisque ce dernier n'est pas un scalaire. Est-ce que le $ fait référence à ce qu'on récupère (donnée qui est dans %tableAliases à l'indice "e") plutôt qu'à l'endroit où on va le chercher (c'est-à-dire %tableAliases lui-même) ?
    Exactement.

    C'est d'ailleurs pour ça qu'il est généralement déconseillé de donner le même nom à des variables de sigils différent : ça peut créer de la confusion à la relecture du code.
    There's nothing like $HOME!

  8. #8
    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
    Citation Envoyé par brunoperel Voir le message
    • Puisque les accolades permettent de délimiter les données du tableau associatif %sqlv_tables, pourquoi ce sont des parenthèses au tout début et à la toute fin de cette déclaration ?
    Parce que dans l'affectation de %sqlv_tables, ce n'est pas une référence que tu définis, mais bien un hash (dans son ensemble), donc une liste de clé/valeur (d'une dimension d'un tableau).
    Dans ce cas, il faut donc bien mettre une liste délimitée par des parenthèses, et non une référence qui ne fournirait qu'une seule valeur scalaire dans ton hash.
    Non, ce n'est pas équivalent.
    Quand j'ai écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    sub getMaxFieldNameLength {
    	my %tableAliases=@_;
    	...
    }
    c'était dans le contexte où l'appel de la fonction se faisait ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getMaxFieldNameLength(%{$sqlv_tables{$tableName}});
    Tu as donc bien fait de poser la question, car dans mon exemple, il y a une erreur dans l'appel
    Ici, on passe en paramètre l'ensemble du hash, que l'on récupère dans @_;

    • Quand on fait :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      $tableAliases_ref->{'e'}
      je ne comprends pas trop pourquoi on met "$" en non "%" devant tableAliases, puisque ce dernier n'est pas un scalaire. Est-ce que le $ fait référence à ce qu'on récupère (donnée qui est dans %tableAliases à l'indice "e") plutôt qu'à l'endroit où on va le chercher (c'est-à-dire %tableAliases lui-même) ?
    Je l'ai expliqué dans mon post précédent : le sigil qu'on place est toujours celui qui correspond au type (scalaire, tableau ou hash) que l'on utilise.
    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

  9. #9
    Inscrit
    Profil pro
    aaaaa
    Inscrit en
    Novembre 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : aaaaa

    Informations forums :
    Inscription : Novembre 2006
    Messages : 178
    Points : 70
    Points
    70
    Par défaut
    Soit dit en passant, j'aimerais savoir pourquoi tu déclares ce dernier avec our. Sans raison spécifique, c'est une mauvaise habitude.
    C'était justement pour éviter de me casser la tête avec le passage des tableaux en argument des fonctions Mais je vais le changer en "my" maintenant que je sais faire ! Cela dit, je ne comprends pas pourquoi on utilise ce "@_" lorsqu'on passe le contenu d'un tableau : pourquoi pas par exemple "@_[0]", similairement à ce qu'on fait pour les scalaires ? Et d'ailleurs, comment ça se passe si on veut passer plusieurs tableaux en arguments ?


    @Philou67430 : OK pour la syntaxe de l'appel dans le cas du passage de la variable par son contenu, je me disais bien qu'il fallait changer quelque chose dans l'appel

    Je suis toujours embrouillé par cette histoire de sigil qui correspond au type de retour et non au type de variable dans laquelle on va chercher l'info. En fait c'est comme si on "castait" la valeur qu'on récupère non ?

    Merci encore ! Je me sens déjà un petit peu plus à l'aise !

  10. #10
    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
    Là où tu déclares ton hash, tu peux le déclarer avec "my" et il sera en fait visible dans tout le programme (sauf si tu en déclares un autre du même nom de portée plus limitée, par exemple dans une fonction ou une boucle.

    @_ contient les arguments passés à la fonction. Si la fonction reçoit un seul scalaire, tu peux effectivement le récupérer en utilisant @_[0] (bien que cette syntaxe soit peu recommandable), ou en faisant un shift sur @_ pour récupérer le premier élément ou même en écrivant "my ($param) = @_;".

    Ici, tu veux récupérer une liste de données. Il faut donc que tu utilises une affectation de liste et non de scalaire.

    Si c'était un simple tableau de valeur, tu pourrais écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @local_param_array = @_;
    Dans le cas présent, c'est en fait un hash, c'est-à-dire une série de couples clé-valeur.

    Tu peux donc écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %local_param_hash = @_;
    Et la liste de valeur indifférenciée de @_ sera "promue" en hash de même que tu peut initialiser un hash en écrivant (ce n'est pas recommandé car peu clair):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %mois = qw (jan 01 fev 02 mar 03 avr 04);
    Il est bien sûr bien préférable (parce que beaucoup plus lisible) d'initialiser ainsi ce hash:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %mois = (jan=>'01', fev=>'02', mar=>'03', avr=>'04');
    Mais je donnais la première syntaxe non recommandée pour bien montrer qu'une simple liste de valeurs se transformait bien en hash dans un contexte de hash.

  11. #11
    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
    Citation Envoyé par brunoperel Voir le message
    Je suis toujours embrouillé par cette histoire de sigil qui correspond au type de retour et non au type de variable dans laquelle on va chercher l'info. En fait c'est comme si on "castait" la valeur qu'on récupère non ?
    Non, ce n'est pas l'équivalent d'un cast.

    Il faut voir deux usages différents du sigil :
    - celui qui permet de "définir" une variable : dans ce cas, il est associé à un opérateur de déclaration comme my, our ou local. Il défini le type du symbole dont tu fournis le nom, à savoir un scalaire, un tableau, ou bien un hash
    - celui qui permet de "déréférencer" un symbole : dans ce cas, il correspond toujours au type qui est déréférencé, et non au type du symbole qui a été initialement défini.

    Exemples :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my %personnel; # défini un hash nommé "personnel".
    $personnel{ouvrier} = [ qw(Paul Matthieu Jean) ]; # créée une clé "ouvrier" dans le hash %personnel, dont la valeur est une référence anonyme à un tableau contenant trois éléments. Cette référence est un scalaire, le sigil devant personnel{employé} est alors un $.
    @{$personnel{comptabilite}} = ( qw(Jeanne Agnes) ); # créée une clé "comptabilite" dont le déréférencement en tant que tableau se voit affecté une liste de deux élément. Le sigil est alors un @
    Je ne sais pas si j'ai été assez clair
    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

  12. #12
    Inscrit
    Profil pro
    aaaaa
    Inscrit en
    Novembre 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : aaaaa

    Informations forums :
    Inscription : Novembre 2006
    Messages : 178
    Points : 70
    Points
    70
    Par défaut
    @_ contient les arguments passés à la fonction. Si la fonction reçoit un seul scalaire, tu peux effectivement le récupérer en utilisant @_[0] (bien que cette syntaxe soit peu recommandable), ou en faisant un shift sur @_ pour récupérer le premier élément ou même en écrivant "my ($param) = @_;".
    J'ai vu ailleurs sur Internet qu'on pouvait utiliser la syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sub maFonction ($$%) {
    	my ($tableAlias,$whereArgument,%sqlv_table_alias_fields) = @_;
    }
    Est-ce que c'est une syntaxe que vous recommandez ? J'ai vraiment du mal à récupérer mes hash si il y a d'autres arguments passés.

    @Philou67430 : Hm, je n'ai pas compris le concept de déréférencement : ton 3ème exemple stocke le contenu d'une variable alors que le 2ème stocke sa référence ?

  13. #13
    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
    Citation Envoyé par brunoperel Voir le message
    J'ai vu ailleurs sur Internet qu'on pouvait utiliser la syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sub maFonction ($$%) {
    	my ($tableAlias,$whereArgument,%sqlv_table_alias_fields) = @_;
    }
    Est-ce que c'est une syntaxe que vous recommandez ? J'ai vraiment du mal à récupérer mes hash si il y a d'autres arguments passés.
    L'usage des prototypes a été un temps déconseillé, de mémoire, mais il semble qu'il ne le soit plus.
    Cela dit, il faut savoir que si tu passes en paramètre des tableaux (ou des hash) par valeur, ceux-ci sont agglomérés tous en ensembles au niveau des paramètres lu par la fonction. Si tu dois passer plusieurs tableau en paramètre, il faut impérativement les passer par référence.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sub maFonction ($$\%\%) {
    	my ($tableAlias,$whereArgument,%sqlv_table_alias_fields, %options) = @_;
    }
    @Philou67430 : Hm, je n'ai pas compris le concept de déréférencement : ton 3ème exemple stocke le contenu d'une variable alors que le 2ème stocke sa référence ?
    Oui, c'est exactement ça.
    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

  14. #14
    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
    A ma connaissance, l'usage des prototypes est toujours déconseillé et un peu dangereux, car ils ne font pas ce que l'on pense généralement qu'ils font.

  15. #15
    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
    Un conseil invitant à éviter les prototypes (datant de 2005) : http://articles.mongueurs.net/magazi...perles-12.html (Prototypage de routine).
    Je n'ai pas encore retrouvé le conseil invitant à les utiliser (de mémoire, c'était relatif à perl6). Toujours est-il que les prototypes ont continuer d'évoluer, et encore dans la version 5.10, avec l'ajout du prototype _.
    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

  16. #16
    Inscrit
    Profil pro
    aaaaa
    Inscrit en
    Novembre 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : aaaaa

    Informations forums :
    Inscription : Novembre 2006
    Messages : 178
    Points : 70
    Points
    70
    Par défaut
    D'accord, merci !

    Je marque le sujet comme résolu. Je n'ai pas eu les réponses à toutes mes questions, mais ces dernières dépassent largement le cadre du passage de hashes. Sur ce point-là, je pense avoir assez de pistes pour me débrouiller. Avec de l'entrainement ça ira mieux

  17. #17
    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
    Un bon article sur le "bon usage" des prototypes (qui ne sert pas contrôler le type des arguments).
    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. Passage de tableaux en paramètre d'une webmethod
    Par VonDutch4520 dans le forum Services Web
    Réponses: 1
    Dernier message: 01/09/2010, 16h59
  2. Réponses: 3
    Dernier message: 05/06/2008, 11h51
  3. Réponses: 7
    Dernier message: 18/05/2005, 15h09
  4. [Tableaux] Interfaces et paramètres non obligatoires
    Par VincenzoR dans le forum Langage
    Réponses: 2
    Dernier message: 07/03/2005, 09h36
  5. Passage de tableaux
    Par jeffS dans le forum MFC
    Réponses: 9
    Dernier message: 02/12/2004, 15h43

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