try/catch in loop?
Ik vraag me eigenlijk af of je een try/catch blok kunt herhalen als ie in de catch terecht komt. En zo ja hoe?
Stel we hebben zoiets als dit:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Kan zoiets?
Gewijzigd op 30/12/2013 20:49:14 door Ozzie PHP
Dus wat doen we dan? Juistem, we returnen true of false. En wat kunnen we dan gebruiken? Juist, een do-while loop!
Overigens is dit de meest vreselijke code die er is. Als je niks hogers dan 10 wilt hebben zet je de rand op 10...
Gewijzigd op 30/12/2013 21:32:09 door Wouter J
Maar kun je een try/catch wel in een loop zetten?
Een ander voorbeeldje dan. Wel redelijk onwaarschijnlijk dat het gebeurt, maar het gaat mij ook om het idee of het kan. We maken een random naam aan voor een (tijdelijke) directory. Vervolgens maken we de directory. Mocht de directory al bestaan (die kans is natuurlijk vrijwel nihil) dan wil ik terug naar het begin van de try. Er wordt dan een nieuwe random naam gemaakt en er wordt weer geprobeerd om de directory aan te maken. Kan zoiets?
Code (php)
Gewijzigd op 30/12/2013 21:41:37 door Ozzie PHP
Ozzie, je zegt het zelf al "het gaat mij ook om het idee of het kan". Als je geen use case kan vinden dan hoeft het ook niet mogelijk te zijn. Als we alles wat wel-mogelijk-had-kunnen-zijn-maar-we-hebben-er-nog-geen-use-case-voor-gevonden in PHP werd geïmplementeerd was die nu 1000 tb en duurde het een uur voordat je script uitgevoerd was.
Code (php)
Maar ik vraag me af of dit de enige manier is, of dat er nog andere mogelijkheden zijn.
Ozzie PHP op 30/12/2013 21:51:35:
Wouter, ik ben meer benieuwd of de constructie mogelijk is. De situatie die ik hierboven schets (al is de kans gering) zou kunnen gebeuren. Mijn vraag is dus of je "terug in de code" kunt op de een of andere manier. Je zou in dit voorbeeld bijvoorbeeld de functie opnieuw kunnen aanroepen:
Maar ik vraag me af of dit de enige manier is, of dat er nog andere mogelijkheden zijn.
Code (php)
Maar ik vraag me af of dit de enige manier is, of dat er nog andere mogelijkheden zijn.
Dat kan, maar als het te vaak fout gaat krijg je een recurion stack overflow. (Niet genoeg geheugen.)
Een loop zou beter zijn:
Ah, oké. Ik wist niet dat dat kon. Geinig. Doet me denken aan mijn Commodore 64 tijd :)
Waarom is het geen best practice?
@Dos:
Ziet er goed uit. Waarom zou je bij het aanroepen van de functie een recurion stack overflow krijgen en bij een loop niet? Waarin zit 'm het verschil? En als je jouw oplossing vergelijkt met de "goto" oplossing van Wouter, heeft een van beiden dan de voorkeur (en waarom)?
en die van dos heeft altijd de voorkeur. Het gebruik van goto statements betekend het verkeerd indelen van je code (zoals je ook al in de cartoon had kunnen lezen)
Ah oké... maar Dos suggereert dat een loop beter is (zoals ik het lees, omdat dit de kans op een recursion stack overflow verkleint).
Dus als je ergens voor de eerste keer $bar->foo() aanroept zal de volgende instructie ($iets =) op die stack geplaatst worden.
Bij de recursive versie zal bij een exception dus de return instructie op die stack gezet worden en vervolgende zal de method foo uitgevoerd worden. Als er telkens een exception gegooit wordt komt dus telkens
die specifieke return instructie boven op de stack terecht.
Op die manier zal je dus na een tijdje niet genoeg geheugen hebben.
Loops hebben dat probleem niet. Als je in C een programma schrijft met "while(1) {}" in de main function zal het CPU vreten maar na eenmaal opgestart is heeft het geen extra geheugen nodig en blijft het draaien tot jij het stopt.
Als je de main functie recursief zou aanroepen gaat het al vrij snel fout: http://stackoverflow.com/questions/2499401/recursive-main-why-does-it-segfault
Gewijzigd op 30/12/2013 22:49:24 door Dos Moonen
Wow, hoe kom jij aan al die kennis Dos? Ik snap je verhaal niet helemaal, maar als ik het goed begrijp stapelt er iets op als je telkens dezelfde functie aanroept, en dat gebeurt niet als je een loop gebruikt? Nou, da's een goede tip om te onthouden! :)
Een stack overflow komt omdat je niet een oneindig grote stack kunt maken omdat er niet genoeg atomen voor zijn =[ Dat betekend dat er een groote voor de stack gekozen moet worden. De groote van de stack bepaald weer hoeveel functies diep kunt gaan.
Als je stack 5 adressen kan bevatten zal het volgende dus al een stackoverflow opleveren.
Code (php)
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
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
<?php
function1() {
function2();
}
function2() {
function3();
}
function3() {
function4();
}
function4() {
function5();
}
function5() {
function6();
}
function6() {
function7();
}
function1();
?>
function1() {
function2();
}
function2() {
function3();
}
function3() {
function4();
}
function4() {
function5();
}
function5() {
function6();
}
function6() {
function7();
}
function1();
?>
Ik heb op school wat (ben absoluut geen expert) spul geleerd over CPU's :p
Gewijzigd op 30/12/2013 23:21:12 door Dos Moonen
En hoeveel stack adressen kan iets normaal dan bevatten? 5 lijkt me niet echt veel...
Bij simpele (recursieve) code hoef je hier vaak geen rekening mee te houden. Maar als de recursie uit de hand begint te lopen zou je je af moeten gaan vragen of het tijd is om te refacteren.
Ah oke...nou, thanks voor de tips in ieder geval :) Ik zal het in m'n achterhoofd houden!