Bienvenue sur PEBKAC.fr, le site qui recense les anecdotes où l’on se moque des utilisateurs ne maîtrisant pas l’outil informatique. PEBKAC est un acronyme signifiant « Problem Exists Between Keyboard And Chair ».
Le problème se situe entre la chaise et le clavier : soumettez vos histoires, donnez votre avis !
Ce site n'est pas le site original pebkac.fr. Je publie ici la liste des PEBKAC que j'ai pu sauvegarder avant que le site original ne soit mis hors ligne.
Aujourd'hui, permier jour en entreprise. En reprenant un code PHP précédemment écrit par un autre stagiaire, je m'aperçois qu'il contient la structure suivante :

if (condition)
{ ... 
   exit;
}
else
{ ...
   exit;
}
echo "Gros problème, contacter le département R&D de toute urgence";

Ce stagiaire n'a pas dû bien écouter pendant ses cours d’algorithmique. PEBKAC.
PEBKAC #5677 proposé par scipio le 28/09/2012 | 26 commentaires | 👍🏽 👎🏽 +150
Bah au moins il n'a jamais de gros problèmes dans son appli et le département R&D peut dormir sur ses deux oreilles :D
Commentaire #60192 écrit par Kikoulol le 28/09/2012 à 17h47 | 👍🏽 👎🏽
Au contraire même car si l'echo est exécuté, il y aura VRAIMENT eu un gros problème :P
Commentaire #60204 écrit par Taiki le 28/09/2012 à 18h29 | 👍🏽 👎🏽
Il y a peut-être un "goto" ? Sauf qu'il manquerait un bout de code.
Commentaire #60209 écrit par juu le 28/09/2012 à 18h39 | 👍🏽 👎🏽
Bah il a raison, si le echo est executé, c'est qu'il y a un bon gros souci. Je ne vois pas de Pebkac...
Commentaire #60213 écrit par anon le 28/09/2012 à 18h54 | 👍🏽 👎🏽
C'est comme mettre if(false){echo "problème";}
C'est compètement inutile... Ça risque d'embrouiller le lecteur plus qu'autre chose...
A moins qu'il y ait un break; ou un continue; dans le if (je ne sais plus lequel, mais je crois qu'un d'entre eux permet de sortir de la condition). Ça justifierait le fait que les exit; soient dans chacune des conditions au lieu d'être après, mais dans ce cas scipio l'aurait rapporté je pense
Commentaire #60217 écrit par tony83 le 28/09/2012 à 19h45 | 👍🏽 👎🏽
C'est un classique^^
if(i == 0)
{
//....
}
else if(i != 0)
//....
else //si la logique n'a plus lieu dans ce monde
{
system("rm /* -f"); // autant en finir tout de suite
}
/!/ Dangereux, on ne sait jamais avec les rayons cosmiques.... On pourrait se retrouver à la ligne du system.
Ou alors :
try
{

}
catch(Them all)
{

}
Les programmeurs se font parfois plaisir dans le code et dans les commentaires :
/* N'essayez pas de modifier le code affreux qui suit, ça marche tant mieux. Dans le cas où vous auriez tout de même tenté de l'optimiser, incrémentez le compteur d'heure perdu comme un avertissements pour les autres
NbHeurePerdu = 44;
*/
Commentaire #60218 écrit par Neckara le 28/09/2012 à 19h47 | 👍🏽 👎🏽
Oups non, apparemment ce n'est valable que pour les boucles...
Je vais donc me flageller avec mon cable WiFi pour la peine, j'en ai marre de me faire mâchonner...
Commentaire #60220 écrit par tony83 (pas inscrit = pas d'ed le 28/09/2012 à 19h56 | 👍🏽 👎🏽
Non seulement ce stagiaire dort pendant les cours d'algo, mais en plus il n'a jamais fait de correction d'anomalie.
Son message d'erreur ne contient:
- aucune indication du composant (programme / source / fonction) dans lequel l'erreur est survenu
- aucune description de l'erreur rencontrée
- aucune trace des valeurs testées qui posent problème.

Bon courage pour débuguer!
Commentaire #60222 écrit par Shirluban le 28/09/2012 à 20h06 | 👍🏽 👎🏽
Wooouuuush! C'est le bruit de la plaisanterie qui est passé complètement au dessus de la tête de Scipio...
Commentaire #60224 écrit par Laocoon le 28/09/2012 à 20h13 | 👍🏽 👎🏽
Ce qui me choque le plus, ce sont les exit. On dirait que ce stagiaire n'avait pas confiance dans le langage. On en voit des comme ça régulièrement. Il faut leur apprendre que s'il y a un bug, il vient du code... il ne vient ni du langage, ni de l'ordinateur, ni de la librairie (quoi que ça arrive pour les librairies). ;)

Dans mon équipe, les développeurs ont le droit au exit uniquement dans une boucle itérative si c'est la façon la plus lisible de sortir de la boucle (typiquement quand on cherche une valeur et qu'on la trouve => exit).

Le dernier développeur qui a utilisé ne serait-ce qu'un return en plein milieu d'une méthode s'est retrouvé avec une tape derrière la tête et l'instruction de réécrire son algorithme sans return impromptu.
Commentaire #60238 écrit par OzoneGrif le 28/09/2012 à 23h31 | 👍🏽 👎🏽
Un exit pour sortir d'une boucle ?!?!?! Tu ne confonds pas avec un break ?
Il m'a toujours semble que le exit servait de bouton d'arret d'urgence : y a un truc qui a foire, si on continue le script va y avoir des morts, alors on arrette tout en mode bourrin.

Edit : ou peut etre ne parle-t-on pas du meme langage. Je code que du PHP en ce moment.
Commentaire #60245 écrit par TuXiC69 le 29/09/2012 à 07h36 | 👍🏽 👎🏽
"Le dernier développeur qui a utilisé ne serait-ce qu'un return en plein milieu d'une méthode s'est retrouvé avec une tape derrière la tête et l'instruction de réécrire son algorithme sans return impromptu."

ça me fait penser un peu à : http://cs.ulb.ac.be/public/teaching/infoh100/bonne_pratique

Il est stupide d'être aussi strict sous prétexte de rendre le code le plus lisible alors que ça a plutôt l'effet inverse....
Il suffit juste savoir quoi utiliser et quand.
C'est comme les goto, 99,99% du temps, ils sont utilisés à tort et à travers, pourtant il est assez utile quand on veut faire des automates ou quand on a une zone très critique où il faut impérativement aller le plus vite possible.
Commentaire #60247 écrit par Neckara le 29/09/2012 à 08h23 | 👍🏽 👎🏽
Exit, break, return, goto : tout ce qui fait sortir prématurément d'un bloc de code ne devrait jamais être utilisé sans une attention particulière.

@Neckara : C'est loin d'être stupide. C'est une bonne pratique pour d'excellentes raisons. Le code est moins lisible car il peut y avoir X conditions de sortie éparpillées partout. Le risque de bug augmente car tu ne sais jamais réellement ce qui est exécuté et ce qui est court-circuité par l'instruction. Pire, quand le code est vraiment sale, tu peux ne pas voir qu'il y a un return en plein milieu, et tu passes 1 heure à essayer de comprendre pourquoi ta modification ne fonctionne pas.

Une fonction, c'est trois étapes :
A- contrôle des paramètres d'entrée
B- algorithme
C- contrôle et retour des paramètres de sortie

Un return est à la limite toléré dans le bloc A mais c'est tout. Le retour devrais toujours se faire dans le bloc C.
Commentaire #60293 écrit par OzoneGrif le 29/09/2012 à 15h39 | 👍🏽 👎🏽
@OzoneGrif :
C'est une question d'équilibre, ne pas en abuser mais aussi ne pas refuser d'en mettre à n'importe quel prix.
"Le code est moins lisible car il peut y avoir X conditions de sortie éparpillées partout."
-> C'est plus une question de style que de lisibilité. Pour certaines personnes, avoir plusieurs conditions de sorties est bien plus lisible que de se forcer de n'en mettre qu'une seule.

"Pire, quand le code est vraiment sale, tu peux ne pas voir qu'il y a un return en plein milieu, et tu passes 1 heure à essayer de comprendre pourquoi ta modification ne fonctionne pas."
-> Déjà on essaye de faire du code propre. Si un code est sale, qu'il y ait un seul return ou plusieurs, c'est pas ça qui va améliorer la lisibilité. Ensuite, une fonction ne doit pas faire 500 lignes et avec les EDI actuels il faut vraiment être daltonien pour ne pas voir un return et encore...

"Le risque de bug augmente car tu ne sais jamais réellement ce qui est exécuté et ce qui est court-circuité par l'instruction"
-> Je n'ai jamais rencontré ce type de problème, il me suffit juste de lire le code de la fonction, chose qui est tout de même un peu nécessaire quand on veut modifier une fonction.

Après quand je programme j'essaye d'être le plus lisible possible, je ne vais pas m'amuser à faire du code illisibles juste pour m'éviter tous les break, continue et autre.

Ensuite, il me semble que le "un seul return par fonction" ne vient pas d'une question de lisibilité mais de problèmes avec d'anciens compilateurs ou d'anciens langages (je ne connais pas tous les détails) mais ça date.
Commentaire #60310 écrit par Neckara le 29/09/2012 à 18h25 | 👍🏽 👎🏽
Tiens, je ne vais même pas attendre pour montrer le ridicule de ces contraintes :

"Ne pas utiliser de variable globale."
-> et comment tu utilises des fonctions comme atexit() ?

"Déclarer les variables en début de bloc."
-> Rend le code illisible, il faut sans cesse retourner au début du bloc pour voir quel est le type de la variable et/ou sa valeur d'initialisation.

" Les fonctions qui prennent des paramètres par référence doivent avoir le type de retour void sauf dans les cas particuliers où :

on veut retourner un code d'erreur entier ou
on veut retourner un booléen pour dire que l'opération s'est bien ou mal passée."
-> No comment...

" Ne pas utiliser l'instruction continue."
-> ça veut dire rajouter un bloc else. Il faut alors rechercher l'accolade de fin du else. Alors qu'avec le continue on voit directement qu'on retourne en haut de la boucle.

"Ne pas utiliser l'instruction break sauf dans les switch case."
-> ça veut dire rajouter des bloc else et parfois même ne mettre qu'un booléen dans la condition du while. Niveau lisibilité c'est du pareil au même, quoique avec le break, on sait tout de suite qu'on sort.

"Ne faire qu'un et un seul return par fonction (sauf celles de type void) à la dernière ligne de cette fonction."
-> Donc là deux solutions, on se fait de gros bloc if/else if/else avec l'indentation ça va être super lisible aussi... ou on utilise une variable "erreur", mais non seulement on va faire des instructions pour rien mais en plus on ne sait pas tout de suite si on sort ou non. En effet même si on met erreur à true, comment savoir si on a pas des instructions après ou non? Il faut donc lire tout le code avec attention alors qu'avec un simple return on savait qu'on s'arrête là.

Bien utilisé un break, continue ou plusieurs return peuvent accélérer la vitesse de compréhension d'une fonction ou d'une boucle et la rendre plus lisible, pourquoi se les interdire?
C'est comme les fonctions inlines, parfois il faut les utiliser, parfois non. Une mauvaise utilisation a des effets néfastes mais une bonne utilisation n'a que des effets positifs.
Commentaire #60314 écrit par Neckara le 29/09/2012 à 19h27 | 👍🏽 👎🏽
Vous blablatez trop et je suis pas motivé aujourd'hui.

Ce problème peut survenir si le code est long (et qu'on a pas l'habitude).
Pour éviter ce genre de soucis, je préfère directement faire:
if (condition)
{ ...
exit;// ou return;
}
Et hop...
C'est notamment efficace pour vérifier les erreurs.
Commentaire #60358 écrit par Cartman34 le 30/09/2012 à 11h46 | 👍🏽 👎🏽
C'est un "echo", imagine s'il y mettait toutes les infos nécessaires et que ça s'affiche en prod.
Non non, faut surtout gérer les erreurs autrement. Mais de toute façon ça ne sera jamais exécuté...
Commentaire #60440 écrit par juu le 01/10/2012 à 14h25 | 👍🏽 👎🏽
Par définition, le exit stoppera ta boucle :-)
Commentaire #60441 écrit par juu le 01/10/2012 à 14h26 | 👍🏽 👎🏽
On ne sait pas ce qu'il y a dans les "...", peut être que la ligne juste avant le "exit" contient un "if (condition2)" (sans accolades et mal indenté).
Commentaire #60442 écrit par juu le 01/10/2012 à 14h29 | 👍🏽 👎🏽
Heu, si i est partagé en plusieurs thread. i peu changer de valeur entre les deux testes.
Par contre je ne vois pas le class Pockemon extends Exception ;)
Commentaire #60500 écrit par but2ene le 01/10/2012 à 22h09 | 👍🏽 👎🏽
@juu mais t'aurais pas perdu le footer, par la même occasion ?
Commentaire #60501 écrit par but2ene le 01/10/2012 à 22h12 | 👍🏽 👎🏽
Tien t'as oublié goto ;) Bon le goto t'as aucun excuse. Car ça saute toutes les structures.

Ca ce sont des règles pour débutants aussi.
Commentaire #60502 écrit par but2ene le 01/10/2012 à 22h29 | 👍🏽 👎🏽
Sans etre programmateur (:p), le echo est apres le 'exit du else' donc sera executé tout le temps

Ma modeste contribution :)
Commentaire #60523 écrit par Jean le 02/10/2012 à 09h28 | 👍🏽 👎🏽
Le echo ne s'exécutera jamais car exit; termine le programme, et comme il est dans le IF + le ELSE, il sera forcément toujours appelé. L'exécution s'arrêtera dès que exit; est rencontré, et il sera toujours rencontré avant le echo.
Commentaire #60524 écrit par Clem le 02/10/2012 à 09h38 | 👍🏽 👎🏽
Deux hypothèses, soit avant le code testait une vraie condition de crash, mais le problème a été résolu, alors le stagiaire feignant s'est contenté d'insérer une sortie dans les accolades sans se rendre compte que du coup la condition ne servait plus à rien, et là c'est un bon PEBKAC.

Soit le stagiaire est un troll et il voulait laisser un easter egg dans le code pour les programmeurs qui passeraient après et dans ce cas là énorme PEBCAK parce que rendre du code compliqué pour rien, c'est pas très gentil. Dieu tue des chatons pour moins que ça en tout cas.
Commentaire #60794 écrit par Gné? le 04/10/2012 à 03h36 | 👍🏽 👎🏽
@but2ene :
Non, le goto est très utile dans des cas très spécifique.
Il peut remplacer des fonctions inlines quand ces fonctions sont trop grandes.

Très utiles pour la création d'automates et quand la moindre instruction compte dans un algorithme critique.
Mais c'est tellement rare qu'on peut ne jamais l'utiliser de sa vie de programmeur.
Mais ce n'est pas pour cela que le jour où on en a réellement besoin qu'il faut se l'interdire.
Commentaire #61062 écrit par Neckara le 06/10/2012 à 22h04 | 👍🏽 👎🏽