Këto ide të tmerrshme vdiqën një vdekje të ligjshme vite më parë - kryesisht

Unë jam një besimtar i fortë në truizmin e programimit se shumica e veçorive të këqija kanë një arsye të mirë për të ekzistuar. Deklarata shumë e urryer goto mund të dalë nga një strukturë blloku thellë e mbivendosur shpejt dhe pastër, në duar me përvojë. Një sasi e caktuar lirshmërie e tipit lejon që kodi të jetë më i hollë dhe më pak i vështirë. Treguesit e kujtesës mund t'ju bëjnë të urreni jetën, por ata ishin jashtëzakonisht të rëndësishëm për të gjitha vitet që hardueri i kompjuterit ishte më i dobët se një termostat Nest. Dhe kështu me radhë.

Por pastaj mendoj për këto relike të vjetra të pluhurosura dhe kuptoj se disa ide të vjetra të kodit janë aq të këqija sa veprimi më i mirë që mund të bëjmë është t'i vrasim me zjarr. Pa hyrje të mëtejshme, këtu janë 3 veçori të gjuhës programuese që janë sende të maktheve.

1. Në gabim Rifillo Tjetra (VB 6 klasike)

On Error Resume Next merr një qasje që është ideja më e keqe në shumë situata gabimi - thjesht vazhdo! — dhe e bën atë rregullin e paracaktuar për çdo problem. Imagjinoni sikur të reagonim në të njëjtën mënyrë ndaj aksidenteve të jetës reale. Pati një aksident me makinë? Vetëm vazhdoni të vozitni!

' We'll set this just in case we have trouble connecting
' to the database.
On Error Resume Next 
Dim TotalPayment As Decimal
Dim TotalHours As Decimal
Dim HourlyRate As Decimal
TotalPayment = 5000
' Oops forgot to set TotalHours!
' This shouldn't work, but we've got error immunity.
HourlyRate = TotalPayment / TotalHours 
' Everything seems good. Let's update the database!
Call UpdateDatabase(HourlyRate)

Por prisni, bëhet më mirë. On Error Resume Next nuk ka kufi. Ajo do të funksionojë përmes zinxhirëve të gjatë gabimesh që përbëhen si interesi nga një kredi e keqe Payday. Nuk ka nevojë as të jetë në krye të modulit tuaj të kodit (ngjiteni në linjë kudo që dëshironi në kodin tuaj dhe kthehuni në normale kur të jeni gati me On Error Resume 0).

On Error Resume Next garanton që do të arrini në fund të rutinës së kodit, e cila është paksa joshëse e sigurisë. Ju nuk keni nevojë të shqetësoheni për injorimin e një pjese të rëndësishme të kodit të pastrimit. Por ju nuk do të arrini në destinacionin tuaj në të njëjtën formë siç keni filluar. Është si një strategji agresive “faketojeni derisa ta arrini”, përveç se zakonisht nuk ka asnjë mënyrë për ta “marrë atë” pasi të keni dështuar në një detyrë parakusht.

Arsyeja e vetme e mundshme që mund të përdorni On Error Resume Next është nëse nuk keni fare kod për trajtimin e gabimeve dhe thjesht dëshironi të kapërceni të gjitha problemet jo aq të këqija që po injoroni. Për shembull, ndoshta po krijoni me vetëdije një skedar që mund të ekzistojë tashmë, duke vendosur veçori të printerit që mund të mos mbështetet ose po kryeni një llogaritje që mund të ndahet me zero. Ju nuk jeni, objektivisht, një person i mirë në atë moment. ju falim. Por nëse përdorni On Error Resume Next, ju po e shtoni injorancën tuaj duke vazhduar në mënyrë të pamatur drejt një fatkeqësie më të madhe.

Por unë nuk do të gënjej. E përdora - dhe më pëlqeu - shumë kohë përpara se të mësoja të programoja. Dhe tani, kryesisht ka vdekur. VB.NET, versioni aktual i VB-së në botën .NET, zëvendësoi On Error Resume Next me trajtimin e arsyeshëm të strukturuar të përjashtimeve. Apo e bëri atë? Rezulton se ju mund të përdorni ende sjelljen klasike dekadash të trajtimit të gabimeve të VB në .NET modern, duke përfshirë On Error Resume Next. E cila është e çmendur, por fatmirësisht nuk kam parë askënd të provojë.

Thënë kështu, On Error Resume Next ekziston ende në kodin real. Mund ta gjeni duke shkatërruar makro në tabelën e Excel-it që përdor ekipi i shitjeve. Faleminderit, VBA.

2. DoEvents (Format e Windows)

Me një funksion të integruar me emër të paqartë si DoEvents(), ju e dini se jeni duke u vendosur për diçka të shëmtuar. Dhe metoda Application.DoEvents() nuk zhgënjen.

DoEvents() është një problem dikur i popullarizuar, por shumë i rrezikshëm për aplikacionet e Windows që nuk duan të merren me multithreading. Skenari klasik është përditësimi i ndërfaqes së përdoruesit në një rreth të ngushtë. Për shembull, imagjinoni se po kryeni një operacion matematikor që kërkon shumë kohë dhe po vendosni numra në një kuti liste. Përdoruesi nuk do të shohë asnjë nga këta numra të shfaqet derisa të hiqni dorë nga kontrolli dhe të lejoni që Windows të përditësojë dritaren. Në mënyrë tipike, kjo nuk ndodh derisa kodi juaj të përfundojë deri në fund, përveç nëse jeni duke e bërë punën tuaj në sfond në një fije të veçantë.

DoEvents() kërkon që aplikacioni juaj të ndalojë, vetëm për një moment, në mënyrë që Windows të mund të bëjë çfarëdo tjetër që dëshiron. Pra, nëse telefononi DoEvents() në një lak, ndoshta do t'i jepni sistemit operativ një shans për të rilyer dritaren tuaj:

for (int i = 0; i < 1000000; i++) 
{
    listBox.Items.Add(someCalculation(i));
    // This is locking up the UI. We could refactor the code,
    // or just add this wee workaround...
    Application.DoEvents();
}

Por historia shkon drejt greminës nga këtu, dhe shpejt. Problemi është se ju kurrë nuk e dini saktësisht se çfarë do të bëjë DoEvents(). Pjesë të tjera të aplikacionit tuaj mund të marrin mesazhe të Windows (të themi, nëse përdoruesi klikon diku tjetër), dhe ata mund të fillojnë të ekzekutojnë kodin e tyre në hapësirën që krijoni kur telefononi DoEvents(). Kjo tingëllon keq, por në fakt është shumë argëtuese (nëse ju pëlqen korrigjimi i gabimeve në orët e vona të natës), sepse rezultati është paksa i ndryshëm në çdo kompjuter!

Siç e di çdo programues, problemi më i keq nuk është kur diçka nuk funksionon, por kur funksionon në një kompjuter, por ka mjaft ndryshueshmëri sa të dështojë në mënyrë misterioze diku tjetër. Dhe nëse nuk e keni këtë problem tani, DoEvents() ka mjaftueshëm jodeterminizëm për ta prezantuar atë.

Sigurisht, është gjithashtu e vërtetë që filetimi është i vështirë. Por prej vitesh .NET ka pasur mjete të lehta për t'u përdorur si komponenti BackgroundWorker, i cili ju lejon të bëni të gjithë punën tuaj në një lidhje tjetër përmes një modeli të thjeshtë të bazuar në ngjarje. Nuk ka nevojë ta hakoni atë së bashku me DoEvents(), dhe shumë pak njerëz e bëjnë këtë. E megjithatë, ajo është ende aty duke u fshehur në bibliotekën e klasës, e importuar nga VB e vjetër e shkollës dhe aktualisht e aksesueshme në çdo gjuhë .NET, përfshirë C# moderne.

E turpshme.

3. Dynamic Goto (COBOL)

Ndryshe nga çështjet e tjera që kam diskutuar, ky është një tmerr i gjuhës programuese që nuk më ka prekur kurrë personalisht. (Unë mund të jem i moshuar, por nuk jam COBOL i vjetër.) Por kjo veçori është kaq e çmendur sa nuk mund ta shpërfillja.

Imagjinoni se po programoni në një gjuhë të lashtë me deklarata të fshehta të kontrollit të rrjedhës. Më pas zbuluat se kjo gjuhë mund të ndryshojë kodin e saj në kohën e ekzekutimit, duke ndryshuar shtigjet që kalon nëpër struktura të ndryshme sintaksore. E çuditshme! Nëse funksionon, gjithçka mbahet së bashku në një ekuilibër delikat. Nëse nuk funksionon, ju merrni diçka si Krimbi i Ouroboros që gllabëron bishtin e vet.

Tipari që unë po e quaj Goto dinamike njihet siç duhet si deklarata ALTER e COBOL. Kjo ju lejon të ndryshoni një komandë ekzistuese GO TO në mënyrë që të transferojë kontrollin në një seksion tjetër nga ai që është shkruar në kodin tuaj. Një deklaratë GO TO madje mund të ndryshohet dhe ri-ndryshohet, të zhvendoset në pjesë të ndryshme të kodit tuaj si një labirint me rampa jashtë autostradës. Shumë thjesht, ALTER merr gjithçka që ju urreni në GO TO - rrjedhën konfuze, kodin e spagetit - dhe dyfishohet.

Këtu është lloji i strukturës për të cilën po flasim:

IF WS-X = 2 THEN         
     ALTER SELECT-PATH TO PROCEED TO PATH-2.
ELSE IF WS-X = 3 THEN
     ALTER SELECT-PATH TO PROCEED TO PATH-3.
END-IF.
GO TO SELECT-PATH.
SELECT-PATH.
     GO TO PATH-1.

Në këtë shembull, komanda GO TO SELECT-PATH mund t'ju çojë në etiketën SELECT-PATH (e cila më pas ju dërgon në PATH-1). Por në varësi të testit të variablit të mëparshëm, ai mund të rimarrëvehet për t'ju përcjellë në PATH-2 ose PATH-3. Dhe kush e di se çfarë mund të ketë ndodhur diku tjetër në kod. Me fjalë të tjera, nuk mund të thuash me siguri se ku do të çojë një GO TO nëse nuk jeni njohur me të gjithë historinë e ekzekutimit të aplikacionit. Por mos u shqetësoni. Jam i sigurt se ka një regjistër diku që mund ta rishikoni.

Ju mund ta quani këtë metaprogramim, por shumica prej nesh do ta përshkruajnë atë thjesht si një ide shumë të keqe.

Ndoshta, në pajisjet informatike me fuqi të pamjaftueshme të kohës, me një shpërndarje të vogël të memories së grumbullit të thirrjeve, kjo lloj magjie e zezë kishte kuptim (ndoshta?). Dhe - gjithashtu pa dyshim - mund të ketë pasur një kohë kur On Error Resume Next dhe DoEvents() ishin kompromisi më i mirë për problemet e vështira. Sot, rreth 60 vjet pasi gjuha u krijua për herë të parë, deklarata ALTER konsiderohet e vjetëruar dhe është "planifikuar për heqje". Pra, të paktën ata po bëjnë gjënë e duhur.

Herën tjetër që dikush vë në dukje me të drejtë veçoritë në JavaScript, ose çmendurinë e variablave të padeklaruar dhe shtypjen e nënkuptuar në çdo gjuhë, kujtojuni atyre — Gjithmonë mund të jetë më keq. ishte më keq.

Këtu shpresojmë që të mos keni kurrë fatkeqësinë për të takuar këto tmerre në një bazë të vjetër kodesh. Dhe nëse keni neverinë tuaj të preferuar të kodimit të së kaluarës, hidheni në komente!

Abonohu ​​në "newsletter Young Coder" për një email një herë në muaj me historitë tona më të mira teknologjike.