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 :

[langage]& dans appel de procedure


Sujet :

Langage Perl

  1. #1
    Membre du Club Avatar de Batou
    Inscrit en
    Mars 2004
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 71
    Points : 62
    Points
    62
    Par défaut [langage]& dans appel de procedure
    bonjour bonjour,
    j'ai remarque que certains programmaient en mettant un & devant les fonctions qu'ils declarait dans leur code.

    Je m'explique :
    Il y en a qui font comme ca (par exemple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    &do_work($argument);
    sub do_work {
    #blablabla
    }
    Alors que moi j'ai plutot tendance a faire comme ca (par exemple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    sub do_work {
    #blablabla
    }
    my ($variable) = do_work($argument);
    Est-ce que c'est que j'ai pris des cas particuliers sans faire attention ?
    Merci d'avance !
    "It has to start somewhere, It has to start sometime.
    What better place than here, what better time than now?
    " [RATM]

  2. #2
    Membre expert
    Avatar de 2Eurocents
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 177
    Points : 3 166
    Points
    3 166
    Par défaut Re: & dans appel de procedure
    Bonjour,

    Citation Envoyé par Batou
    j'ai remarque que certains programmaient en mettant un & devant les fonctions qu'ils declarait dans leur code.

    ...

    Est-ce que c'est que j'ai pris des cas particuliers sans faire attention ?
    Merci d'avance !
    La réponse se trouve, dès le début, dans la doc perlsub (Les sous-programmes de Perl). A la rubrique synopsis, on trouve :
    Citation Envoyé par perldoc perlsub
    To call subroutine :

    NAME(LIST); # & is optional with parentheses.
    NAME LIST; # Parentheses optional if predeclared/imported.
    &NAME(LIST); # Circumvent prototypes.
    &NAME; # Makes current @_ visible to called subroutine.
    Il est donc évident que ce & a un usage précis : court-circuiter le prototype de la fonction ( pour passer des paramètres distincts ? mais pourquoi faire un prototype, alors ), ou rendre @_ de la fonction courante visible à la fonction appelée.

    Après, savoir si tous les programmeurs Perl utilisent ce & en connaissance de cause, c'est un autre problème.
    La FAQ Perl est par ici
    : La fonction "Rechercher", on aurait dû la nommer "Retrouver" - essayez et vous verrez pourquoi !

  3. #3
    Expert confirmé
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 851
    Points : 4 743
    Points
    4 743
    Par défaut
    Salut

    Je suis d'accord avec 2Eurocents (on ne peut être que toujours d'accord avec 2Eurocents !!!). Perso, j'utilise toujours le & pour cause d'une vieille manie sans doute pas bonne : j'ai la sale manie du C (mais salutaire pour la lisibilité) d'écrire toujours un prototype de fonction et d'y faire référence ! D'où l'emploi systématique du &.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code ni le tag

    Je ne répond à aucune question technique par MP.

  4. #4
    Membre du Club Avatar de Batou
    Inscrit en
    Mars 2004
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 71
    Points : 62
    Points
    62
    Par défaut consequences
    bonjour 2Eurocents, bonjour GLDavid,

    ok, merci bcp pour vos explications. Sans elles, j'aurais pas compris le manuel.
    J'ai pas les habitudes du C, mais je crois avoir compris en gros comment ca fonctionne.
    J'aimerai qd mm, que qqn confirme l'image que je me fais des consequences de :

    "passer par un prototype de fonction" = ca accelere le programme ?

    "rendre visible @_ a la fonction appelee" = ca fait un trou de securite dans les donnees qui circulent entre programme et procedure ?

    Comme je m'y connais pas tellement, c'est possible que ces suppositions soient aussi grosses que moi !
    Merci
    "It has to start somewhere, It has to start sometime.
    What better place than here, what better time than now?
    " [RATM]

  5. #5
    Expert confirmé
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 851
    Points : 4 743
    Points
    4 743
    Par défaut
    Salut

    Prototyper une fonction n'accélère pas le programme mais te permet de fixer les règles de ta fonction. Par exemple, prenons la fonction psuh. Celle-ci prend 2 arguments : un tableau et un scalaire. Le prototype de cette fonction serait : push(\@$$). La fonction attend une référence sur une liste puis une référence sur un scalaire.
    Ensuite pour ta question sur @_, ce n'est pas une fuite. C'est juste un passage des arguments données.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code ni le tag

    Je ne répond à aucune question technique par MP.

  6. #6
    Expert confirmé
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 851
    Points : 4 743
    Points
    4 743
    Par défaut
    Resalut

    Voici un petit code que j'ai préparé pour te montré comment utiliser les prototypes :
    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
     
    #!/usr/bin/perl -w
     
    use strict;
    use Carp;
     
    sub mypush(\@$){
    	my $tablo = $_[0];
    	my $var = $_[1];
    	push(@$tablo, $var);
    }
     
    my(@tab);
    mypush(@tab, "foo");
    mypush(@tab, "bar");
     
    foreach(@tab){
    	print;
    }
     
    print "\n";
    La fonction mypush attend d'abord une référence sur un tableau (une liste) puis un scalaire. En plus, ça me donne des idées d'évolutions pour la FAQ

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code ni le tag

    Je ne répond à aucune question technique par MP.

  7. #7
    Fabouney
    Invité(e)
    Par défaut
    Bonjour,

    donc en gros passer par un prototype, ca allége l'écriture de la fonction ?

    A+

  8. #8
    Membre expert
    Avatar de 2Eurocents
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 177
    Points : 3 166
    Points
    3 166
    Par défaut
    Citation Envoyé par Fabouney
    donc en gros passer par un prototype, ca allége l'écriture de la fonction ?
    Même pas ... ou si, mais juste un peu.

    Ca permet surtout de savoir de quoi on va parler.

    Du coup, l'interpréteur peut se plaindre si l'appel ne correspond pas à la description qui en est faite dans le prototype.

    C'est pareil en C, le compilateur se plaint si l'appel a des paramètres différents de la déclaration (à ne pas confondre avec la définition, qui est le code de la fonction). Si les déclarations sont mises, sans la définition, avant le code qui leur fait appel, on parle de prototypes.


    Accessoirement, pour en revenir à Perl, préfixer l'appel par un & permet de court-circuiter la vérification par rapport au prototype. On perd donc ce mécanisme de contrôle, et la récupération des paramètres doit être un peu plus corsée pour s'assurer que l'on a bien ce que l'on était sensé avoir ...

    C'est peut être sur le point du contrôle de la cohérence des paramètres que l'usage des prototypes peut alléger l'écriture des fonctions ... et puis ça fait toujours un contrôle de plus sur la qualité du code
    La FAQ Perl est par ici
    : La fonction "Rechercher", on aurait dû la nommer "Retrouver" - essayez et vous verrez pourquoi !

  9. #9
    Fabouney
    Invité(e)
    Par défaut
    Ok, merci pour ces renseignements, on se couchera un peu moin bête ce soir ! et merci a Batou, par la question initiale lol .

    bonne journée à tous

  10. #10
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par Fabouney
    donc en gros passer par un prototype, ca allége l'écriture de la fonction ?
    non, ça le rend beaucoup plus chiant à utiliser.

    Si tu as un sub défini comme tel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sub ajout ($$) {
        return $_[0] + $_[1];
    }
    alors ceci ne compile pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my @arg = ( 2, 7 );
    print ajout(@arg);
    Bien que le nombre de paramètres soit correct, le prototype force le passage de deux scalars. Il faut écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print ajout( $arg[0], $arg[1] );
    ce qui, des fois, est assez pénible. En règle général, c'est simple : tu n'utilise JAMAIS de prototypes. On les considère comme une experience scientifique qui a échoué.

    La seule raison encore valable est le passage de coderefs, ce qui permet d'écrire des routines qui ressemblent syntaxiquement aux grep et map.

    N

  11. #11
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut Re: & dans appel de procedure
    Citation Envoyé par Batou
    j'ai remarque que certains programmaient en mettant un & devant les fonctions qu'ils declarait dans leur code.
    C'est une archaïsme qui date de l'époque Perl 4 (autrement dit, le siècle dernier).

    Continues à utiliser les parenthèse sur les appels de subs, c'est très bien comme ça.

    N.

  12. #12
    Rédactrice

    Avatar de stoyak
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    408
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 408
    Points : 1 491
    Points
    1 491
    Par défaut
    déjà, tes deux exemples sont differents dans le sens où le deuxième te renvoie une valeur et pas le premier. maintenant, pour moi, y'a pas de difference significative entre procedure($variable) et &procedure($variable).
    l'esperluette etait requise dans les vieilles versions de perl, mais elle est généralement omise aujourd'hui. malgré cela, elle est quelque fois nécessaire comme par exemple quand tu passes la fonction en référence (ex utilisation du module File::Find).
    Cela demande du courage d'en tirer du plaisir
    Quand on n'a qu'un marteau, tous les problèmes ressemblent à un clou

  13. #13
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par stoyak
    ... quelque fois nécessaire comme par exemple quand tu passes la fonction en référence (ex utilisation du module File::Find).
    Non, pas tout à fait, c'est plutôt le \& qui est important, pas l'esperluette toute seule, sinon la routine est executé sur le champ. Le & en ce cas est pour signifier quelle partie du typeglob nous interesse.

    Un sub anonmye (donc, dans une variable lexique) n'as pas besoin de & en passage à File::Find.

    N

  14. #14
    Rédactrice

    Avatar de stoyak
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    408
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 408
    Points : 1 491
    Points
    1 491
    Par défaut
    Citation Envoyé par nematoad

    Non, pas tout à fait, c'est plutôt le \& qui est important, pas l'esperluette toute seule, sinon la routine est executé sur le champ.
    c'est bien ce que j'ai dit!! il faut tjs le \ pour passer en référence et c'est donc bien l'association de \& qui est important dans l'exemple que j'ai donné!
    Cela demande du courage d'en tirer du plaisir
    Quand on n'a qu'un marteau, tous les problèmes ressemblent à un clou

  15. #15
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par stoyak
    c'est bien ce que j'ai dit!! il faut tjs le \ pour passer en référence et c'est donc bien l'association de \& qui est important dans l'exemple que j'ai donné!
    Oui, certes, mais c'est nullement obligatoire. Si tu as un coderef anonyme tu n'en as pas besoin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    use File::Find;
     
    my $x = sub { print "$File::Find::name\n" if -d $_ };
    find( $x, '.' );
    Pas d'esperluette à l'horizon. Dans ton exemple 'procedure' stocké dans le slot CODE du typeglob *procedure, qui se trouve dans le hash %::. Il faut ajouter & pour spécifier quel slot s'agit-il, et \ pour prendre une référence sur le résultat. Comme c'est assez laid comme syntaxe, on trouve généralement que les gens écrivent

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    use File::Find;
    find(
        sub { print "$File::Find::name\n" if -d $_ },
        '.'
    );
    N

  16. #16
    Membre du Club Avatar de Batou
    Inscrit en
    Mars 2004
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 71
    Points : 62
    Points
    62
    Par défaut mission completed
    ok !

    Merci a toutes et a tous ! J'ai finalement compris comment et pourquoi on utilise les proto.

    Special tks to :
    2Eurocents (vriament trop fort)
    GLDavid
    Nematoad
    et Fabouney

    Pour moi, c'est resolu, bonne journee !
    "It has to start somewhere, It has to start sometime.
    What better place than here, what better time than now?
    " [RATM]

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

Discussions similaires

  1. Appels de procedures stockées dans une proc stockée ?
    Par Nadaa dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 17/07/2008, 11h32
  2. appel de procedure dans un trigger
    Par madimane dans le forum Oracle
    Réponses: 3
    Dernier message: 14/03/2006, 07h59
  3. Réponses: 4
    Dernier message: 26/01/2005, 14h08
  4. Réponses: 3
    Dernier message: 21/09/2004, 08h35
  5. Réponses: 1
    Dernier message: 04/06/2003, 12h48

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