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 Delphi Discussion :

Quitter la fonction appelante


Sujet :

Langage Delphi

  1. #1
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut Quitter la fonction appelante
    Bonjour,

    Relisant de nombreuses lignes de code dans le cadre d'une migration de projet, je trouve souvent ce genre de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure truc;
    begin
    if not freponse('blabla') then
    begin
      ShowMessage('lalala');
      exit;
    end;
    ...
    end;
    Je trouve ça lourd et je me dis qu'il y a peut-être une façon de faire autrement. Par exemple :

    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
     
    procedure test(t, m: string);
    begin
     if not t then
     begin
      ShowMessage(m);
      ExitFonctionAppelante;   <<<---------
     end;
    end;
     
    procedure truc;
    begin
      test(freponse('blabla'), 'lalala');  
    end;
    ...
    end;
    Vous en pensez quoi ?

    Bien sur, on mettre chaque test dans un try..except et déclencher une exception silencieuse mais je trouve ça encore plus "bof".

    Papy !

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 671
    Points : 25 481
    Points
    25 481
    Par défaut
    Alors un Exit sur plusieurs niveaux n'existe pas, je ne crois pas non plus que le break puisse sortir de plusieurs boucles comme dans certains langages !?

    Le problème, c'est qu'il me semble difficile de généraliser !
    Personnellement mes fonctions ne contient JAMAIS de ShowMessage sauf si ce sont des méthodes d'un TForm !
    J'ai une tendance à mettre le moins possible de code intelligent dans le TForm et a déporter la logique métier dans des objets métiers et plus ou moins dans des objets intermédiaires que l'on pourrait assimiler à des contrôleurs (MVC)

    Je préfère un système de code d'erreur ou une exception (une vraie avec message et tout le tralala pas juste un abort)

    personnellement je préfère écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure truc;
    begin
    if freponse('blabla') then
    begin
      ... traitement
    else
      ShowMessage('lalala');
    end;

  3. #3
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut
    J'utilise aussi ce système d' "exception" personnalisée mais j'ai lu par ici qu'il faut éviter de les utiliser à mauvais escient. Alors je me posais la question d'une autre solution.

    Dans certaines unités du projet que je traite, il y a parfois 7 ou 8 cas traités par un "if..then exit" . Ca fait des procédures à rallonge.

    Le exit(nomfonction) serait une bonne alternative. Dommage que ça n'existe pas.

  4. #4
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut en fait, on dirait bien que si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    procedure test01;
    begin
      abort;
    end;
     
    procedure TForm7.Button6Click(Sender: TObject);
    begin
      test01;
      ShowMessage(FormatDateTime('"Nous sommes le "dd-mm-yyyy', now));
    end;
    Ne déclenche pas le ShowMessage


    ce qui revient à une exception silencieuse, j'en conviens

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    J'utilise aussi ce système d' "exception" personnalisée mais j'ai lu par ici qu'il faut éviter de les utiliser à mauvais escient. Alors je me posais la question d'une autre solution.

    Dans certaines unités du projet que je traite, il y a parfois 7 ou 8 cas traités par un "if..then exit" . Ca fait des procédures à rallonge.

    Le exit(nomfonction) serait une bonne alternative. Dommage que ça n'existe pas.
    je ne comprend pas bien ton problème...

    le mécanisme des exceptions est pratique pour sortir d'une sous-sous-sous procédure, mais ça complique la gestion des erreurs, on lui préfère donc Exit

    ensuite rien ne t'empêche d'utiliser des sous-fonction

    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
     
    procedure truc;
    begin
      if cond1 then 
      begin
        code1;
        exit;
      end;
      if cond2 then 
      begin
        code2;
        exit;
      end;
    end;
     
    // remplacé par
     
    function code1: Boolean;
    begin
      Result := cond1;
      if Result then
       ..
    end;
     
    function code2: Boolean;
    begin
      Result := cond2;
      if Result then
       ..
    end;
     
    procedure truc;
    begin
      if code1 or code 2 then
      Exit;
    end;

  6. #6
    Membre averti Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Points : 443
    Points
    443
    Par défaut
    Me concernant, je n'utilise jamais "Exit" car je trouve qu'il rend la lecture du code plus compliqué.
    C'est un peu comme les goto. En fait c'est un goto qui renvoie à la fin de la procedure, ni plus ni moins et ce n'est vraiment pas élégant.
    Il y a d'autres solutions plus élegantes pour cela, comme utiliser un boolean par exemple. C'est souvent exploité pour traiter des erreurs retournées par des fonctions.
    C'est sur qu'il faut taper plus de lignes mais c'est quand même plus élégant.
    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
     
    Function test(t, m: string) :boolean;
    Var Err:boolean;
    begin
      Err:=false;
      if not t then
      begin
        ShowMessage(m);
        Err:=true;
      end;
      result:=Err;
    end;
     
    Function truc:boolean;
    Var Err: boolean;
    begin
      result:=test(freponse('blabla'), 'lalala');  
    end;
    ...
    end;

  7. #7
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Je trouve ça aberrent de limiter l'utilisation de fonction de base parce que c'est pas "élégant"

    Pour ma part j'utilise régulièrement des exit dans mes codes et il ne sont pas pour autant plus illisible qu'avec des if imbriqués.

    Je préfère largement en lecture

    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
     
    function test : Boolean
    begin
      Result := False;
     
      If Test1 Then
      begin
        Showmessage('Test1');
        Exit;
      end;
     
      If Test2 Then
      begin
        Showmessage('Test2');
        Exit;
      End;
     
      Result := True;
    end;
    Que ce code la

    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
     
    function test : Boolean
    begin
      Result := True;
     
      If Test1 Then
      begin
        Showmessage('Test1');
        Result = False;
      end
      else If Test2 Then
      begin
        Showmessage('Test2');
        Result := False;
      End;
    end;

  8. #8
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut
    Paul:
    Mon problème n'est pas dans la pertinence du code mais juste dans un souci de concision. Je trouve très souvent dans ce gros projet sur lequel je travaille des choses du genre:

    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
     
    if kekchose1 then
    begin
      ShowMessage('blabla');
      exit;
    end;
    if kekchose2 then
    begin
      ShowMessage('blabla');
      exit;
    end;
    if kekchose3 then
    begin
      ShowMessage('blabla');
      exit;
    end;
    if kekchose5 then
    begin
      ShowMessage('blabla');
      exit;
    end;
    if kekchose6 then
    begin
      ShowMessage('blabla');
      exit;
    end;
    if kekchose7 then
    begin
      ShowMessage('blabla');
      exit;
    end;
    if kekchose8 then
    begin
      ShowMessage('blabla');
      exit;
    end;
     
    ....
    Chaque test étant bati sur le même modèle. Bien sur que ça fonctionne, ainsi que le code que tu proposes. Mais j'ai des manies de vieux, j'aime faire des choses plus courtes et factorisées autant que faire se peut. De toutes manières, je ne changerai pas le code existant, ce n'est pas le but du travail demandé. Ce n'était qu'une question pour une utilisation future.

    Au fait, y fait beau en ce moment dans les iles ?

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 671
    Points : 25 481
    Points
    25 481
    Par défaut
    Papy214, tu n'aurais pas quelques codes courts à nous fournir en exemple, des cas concrets, car sinon cela risque juste d'être un débat de formattage de code source qu'une réponse à ton problème !

    En même temps, c'est si juste ç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
    if kekchose1 then
    begin
      ShowMessage('blabla');
    end
    else if kekchose2 then
    begin
      ShowMessage('blabla');
    end
    else if kekchose3 then
    begin
      ShowMessage('blabla');
    end
    else if kekchose5 then
    begin
      ShowMessage('blabla');
    end
    else if kekchose6 then
    begin
      ShowMessage('blabla');
    end
    else if kekchose7 then
    begin
      ShowMessage('blabla');
    end
    else if kekchose8 then
    begin
      ShowMessage('blabla');
    end;
     
    ....
    Après, si tu as un retour, comme le fait remarquer Rayek, il ne faut pas être trop rigide, parfois une écriture convient mieux pour la lisibiliter, parfois une autre !

    Sinon, si tes kekchoseN sont tous de la même forme (même paramètre) ou que tu peux faire en sorte qu'il soit tous pareils, cela peut se faire dans une boucle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for i := 1 to 8 then
    begin
      p := MethodAddress(Format('kekchose%d', i));
      if Tkekchos(p)(param, message) then // param un objet, message une string en out
        ShowMessage(message);
    end;
    MethodAddress pouvant être remplacé par un tableau de fonction comme je l'avais fait là : Déclaration de pointeur de fonction et structure

    En standardisant ton système (un controle de saisie je suppose, une validation des donnés ?) dans un objet utilitaire, tu pourras le réutiliser avec un minimum de code !
    Juste après il faut déclarer les méthodes en published ou alors créer un Mapping sous forme de constante : Tableau Dynamique pointant sur Tableau Statiques

  10. #10
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut
    En standardisant ton système (un controle de saisie je suppose, une validation des donnés ?) dans un objet utilitaire
    C'est effectivement juste une question générale sur la l'écriture du code dans ce cas que l'on retrouve très souvent. Le projet en question contient environ 200 formulaires, chacun avec au moins une procédure contenant ce genre de code. Comme je dois passer dans toutes ces unités pour vérifier certaines choses, à force de voir tous ces tests bâtis sur le même principe, je me demandais si on n'aurait pas pu faire plus court.

    C'est plus une question de style que de fonctionnalités :-)

  11. #11
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    EXIT, c'est ma préférée, et je la mets toujours en Majuscules comme BREAK, et CONTINUE ... et pour la concision j' n'hésites pas à faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function test : Boolean;
    begin     Result := False;
              If Test1 Then begin Showmessage('Test1'); EXIT; end;
              If Test2 Then begin Showmessage('Test2'); EXIT; end; 
              Result := True;
    end;
    et ça ne nuit pas à la lisibilité... mais à chacun ses goûts.

    A+.

  12. #12
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut
    Je rajouterai pour Shai que ça va dans le même sens que ma question récente intitulée: "Type de classe en paramètre de fonction"

    Dans le code, je vois régulièrement des
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    With TMYForm.Create(self) do
    begin
      ShowModal;
      Release;
    end;
    Ma question avait pour but de réduire ça partout à une seule ligne par un simple appel à une fonction prenant en paramètre le type de la TForm à afficher. Ce qui permettait d'avoir une seule ligne de code à chaque fois plutôt que 5.

    Maintenant, tout "factoriser" comme ça n'est pas forcément bon, je suis d'accord.

  13. #13
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,

    EXIT, c'est ma préférée, et je la mets toujours en Majuscules comme BREAK, et CONTINUE ... et pour la concision j' n'hésites pas à faire ceci :

    et ça ne nuit pas à la lisibilité... mais à chacun ses goûts.

    A+.
    Là, c'est plus de la présentation de code. Perso, je suis pour une indentation à tous les étages, mais effectivement, chacun ses gouts.

    Par contre, tu risques de lancer un débat passionné sur le sujet

  14. #14
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    Je rajouterai pour Shai que ça va dans le même sens que ma question récente intitulée: "Type de classe en paramètre de fonction"

    Dans le code, je vois régulièrement des
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    With TMYForm.Create(self) do
    begin
      ShowModal;
      Release;
    end;
    Normalement pour être vraiment propre ton code devrait être un peu plus long

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    With TMYForm.Create(self) do
    Try
      ShowModal;
    finally
      Release;
    end;


    Citation Envoyé par Papy214 Voir le message
    Ma question avait pour but de réduire ça partout à une seule ligne par un simple appel à une fonction prenant en paramètre le type de la TForm à afficher. Ce qui permettait d'avoir une seule ligne de code à chaque fois plutôt que 5.

    Maintenant, tout "factoriser" comme ça n'est pas forcément bon, je suis d'accord.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure TForm1.CreateAndShow(AFormClass : TFormClass);
    var
      UneForm : TForm;
    begin
      UneForm := AFormClass.Create(Self);
      Try
        Uneform.ShowModal;
      Finally
        UneForm.Release;
      End;
    end;

  15. #15
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 671
    Points : 25 481
    Points
    25 481
    Par défaut
    Citation Envoyé par Rayek Voir le message
    Normalement pour être vraiment propre ton code devrait être un peu plus long
    oui, dans ma réponse de Type de classe en paramètre de fonction, j'avais mis le try finally !

    Rayek, tu sais pour un ShowModal, tu peux faire un Free sans risque, pas besoin d'un Release qui est utile si l'on libère dans un gestionnaire d'évènement !


    Citation Envoyé par Papy214 Voir le message
    Je rajouterai pour Shai que ça va dans le même sens que ma question récente intitulée: "Type de classe en paramètre de fonction"

    Tiens, un sujet C++ Builder : Appel d'une fonction/TThread de façon paramétrique, c'est transposable en Delphi et ça te donne une idée des possibilités de généralisation !

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

Discussions similaires

  1. fonction appelante javascript
    Par kimcharlene dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 07/08/2007, 15h06
  2. [javascript] Retrouver nom de la fonction appelante
    Par lenoil dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 06/08/2007, 12h10
  3. Réponses: 3
    Dernier message: 01/05/2007, 12h03
  4. Connaitre la fonction appelante
    Par linar009 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 27/07/2006, 08h46
  5. DLL, fonctions appelées, fonctions appelantes
    Par kantelise dans le forum Windows
    Réponses: 1
    Dernier message: 10/05/2006, 13h26

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