Bail out from parent procedure

Just starting out? Need help? Post your questions and find answers here.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Bail out from parent procedure

Post by Trond »

Basically I want to create a program that is constantly running (like the PB compiler). It can then accept data and process it.

If the data has errors, the program will probably be in some deeply nested procedure when it finds the error. The program should then then stop the processing, but continue running and waiting for other data.

What is the best way to handle this, and return to a clean main loop after an error?
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

Absolutely simplest way is to do a restart.

Another solution i use myself: Have the place you are nested in check for a
global "quit" variable. If its 1, exit the loop. The quit variable can be checked from many places, or simply written directly in the process, which is quite easy and safe.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

If I restart, I have to reload static data.
If I use a global error variable, I have to check this in A LOT of places.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

the problem is:
if you want to jump out, you at least have to know how deep in sublevels the code is,
because you'll have to POP every backjump-data from the Stack to continue with the mainloop.
so you would have to keep trace of the nesting-level.

the global "quit" is a practicable solution.

also it would be possible to give ALL(!) of your procedures the possibility to return an error-code,
wich will cause also the parent-proc to return-with-error immediately.

in every case you'll have to integrate it completely into your concept,
it is nothing to implement later easily....
oh... and have a nice day.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You could of course place the processing within a thread and use WaitThread() in the main code etc. Then again, not much point in a thread if the main code is then stuck waiting I guess. Just an idea!
I may look like a mule, but I'm not a complete ass.
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

srod wrote:You could of course place the processing within a thread and use WaitThread() in the main code etc. Then again, not much point in a thread if the main code is then stuck waiting I guess. Just an idea!
This is exactly what he wants to avoid :)

I think the global quit-check is the safest solution. If you have a lot of nested loops, just check in the larger ones. if you have eg:

For i=1 to totalLines
for a = 1 to totalLines
;do your stuff
next a
;Check here
next i

Still a lot of checks.
Last edited by thefool on Thu Mar 15, 2007 8:02 pm, edited 1 time in total.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

There should be a built-in feature for this in modern programming languages. That would be really cool.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

This is exactly what he wants to avoid
really?

I think it's a good approach...

the complete processing can be within a thread that will be terminated if an error occurs,
so the level of nesting is no longer a problem and the main-thread isn't touched at all....
oh... and have a nice day.
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

Trond wrote:There should be a built-in feature for this in modern programming languages. That would be really cool.
Its so easy to make one using BREAK.
'Why would the other method be better?
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

Kaeru Gaman wrote: the complete processing can be within a thread that will be terminated if an error occurs
And you call this SAFE?
besides he said to use WAIT THREAD. wait thread waits till a thread stops, no point except you get more overhead usign a THREAD. THINK!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

What's unsafe about it? Providing you don't use KillThread() and just use ProcedureReturn etc,
I may look like a mule, but I'm not a complete ass.
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

srod wrote:What's unsafe about it? Providing you don't use KillThread() and just use ProcedureReturn etc,
Because he don't want to wait for the processing to finish. Nothing unsafe, but then there is no point in it!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yea, I agree on that score - it was just something to throw into the pot! I guess we need to know a little more about the structure of the procedure before being able to really comment.

Then again I guess the structure of the procedure is exactly what Trond is asking about. Personally, I farm every step of the data processing out to a separate function, which is only called if the preceeding one does not flag an error rather than try and nest it within one big procedure. But that is just personal preference. I find it leads to some easily maintainable code etc.
I may look like a mule, but I'm not a complete ass.
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

srod wrote: Then again I guess the structure of the procedure is exactly what Trond is asking about. Personally, I farm every step of the data processing out to a separate function, which is only called if the preceeding one does not flag an error rather than try and nest it within one big procedure. But that is just personal preference. I find it leads to some easily maintainable code etc.
Yeah i tend to split it apart too. And then have one procedure to hold the loop which call the others. But it still leads to the same question, how do he test when to stop! I think the only real solution is the quit variable. Then he need to place it at the right spot
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Code: Select all

For i=1 to totalLines 
for a = 1 to totalLines 
;do your stuff 
next a 
;Check here 
next i
That's a working way to do it, but the problem is that this is not a simple loop, it's a huge program. So inside "do your stuff" there will be tons of other loops and procedure calls.
With the global error variable, if I have a procedure which is called from a lot of places, and should stop the process if it fails, I would have to check it after every call, instead of processing the failure inside the function.
You could of course place the processing within a thread and use WaitThread() in the main code etc. Then again, not much point in a thread if the main code is then stuck waiting I guess. Just an idea!
Even if I place the code in a thread, how to I stop in the middle of the thread?
the complete processing can be within a thread that will be terminated if an error occurs,
so the level of nesting is no longer a problem and the main-thread isn't touched at all....
I will have to allocate a lot of memory, which will be flushed down the toilet when I use KillThread().
What's unsafe about it? Providing you don't use KillThread() and just use ProcedureReturn etc,
If I only use ProcedureReturn there's no extra benefit in using a thread.

thefool wrote:
Trond wrote:There should be a built-in feature for this in modern programming languages. That would be really cool.
Its so easy to make one using BREAK.
'Why would the other method be better?
This is the current way of doing it:

Code: Select all

Global Current.c
Global ErrorOccured = 0

Procedure GetChar()
  If Eof(0)
    ErrorOccured = 1
  EndIf
  Current = ReadCharacter(0)
EndProcedure

; Call
GetChar()
If ErrorOccured
  ProcedureReturn
EndIf
That really isn't funny any more when you call GetChar() from 40 different places inside your program. And to do this for every function that can fail will make the code be more error handling than actual code. Especially, since every function that uses a function that can fail now can fail as well.

Compare to build-in handling(pseudocode):

Code: Select all

Global Current.c
Global ErrorOccured = 0

Procedure GetChar()
  If Eof(0)
    BailTo(MainLoop)
  EndIf
  Current = ReadCharacter(0)
EndProcedure

Procedure MainLoop()
  ; Waiting for orders
EndProcedure

; Call
GetChar()
Then again I guess the structure of the procedure is exactly what Trond is asking about.
Yes!
Personally, I farm every step of the data processing out to a separate function, which is only called if the preceeding one does not flag an error rather than try and nest it within one big procedure. But that is just personal preference. I find it leads to some easily maintainable code etc.
That's what I do as well, and I find it leads to 3 lines of error checking for every 1 line of program logic. Which is sort of boring.
Post Reply