Jump to content

Return level from function, like ExitLoop level from loop?


Go to solution Solved by trancexx,

Recommended Posts

Posted

hello world,

i'm looking for some method like ExitLoop level, but for Return from functions (not confusing with function return value).

i.e. ExitLoop can get you out of a loop1, and out of loop2 that loop1 is in, if you specify level 2.

i want to call func1, and func1 needs to call func2, and i want func2 to return to func1 and make func1 also return to the calling script.

currently i'm doing it with a condition check, but i'm looking for something more elegant, and with less code lines.

Func func1()
    If True Then    ; the condition that makes func1 call func2
        func2()
        Return
    EndIf
EndFunc
Func func2()
    Return ; how to make return level 2 that will also make func1 return?
EndFunc

i want func1 to look like this:

Func func1()
    If True Then func2()    ; func1 will return upon func2 return, so the next lines in func1 are not executed
    ; do something
EndFunc

ok, so it does not make a lot of sense in this short example, but over a longer project, the coding difference is apparent.

any ideas are welcome, thanks all.

Signature - my forum contributions:

  Reveal hidden contents

 

Posted

You will have to design your own. Why not use SetError instead and using Return 2 won't return from the 2nd function.

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

Posted

i figured this much, but that will still impose a Return statement in func1 right after the call to func2, and this is what i want to avoid.

Signature - my forum contributions:

  Reveal hidden contents

 

Posted

Sorry, trancexx is on the mark. It's early, that's my excuse.

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

  • 7 years later...
  • Moderators
Posted

zkenjiz,

Welcome to the AutoIt forums.

The answer from trancexx a couple of posts above is the answer.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

  • Developers
Posted
  On 2/11/2021 at 4:11 AM, zkenjiz said:

After 8 years, there are no answer for this, I need it too, sad.

Expand  

First post and unable to read...  sad. ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Posted
  On 2/11/2021 at 8:01 AM, Melba23 said:

zkenjiz,

Chào mừng đến với diễn đàn AutoIt.

Câu trả lời từ trancexx một vài bài viết trên là câu trả lời.

M23

Expand  

Thanks, but that answer not match the question. As above question, I don't think there a many many line with "If Not _Func() Then Return" to come back main loop at anytime when event catched is a good choose. 

Posted

Sorry for the translated quoted.

This is an example code I using a custom sleep function to Sleep() and check event all the time. The problem I find for this situation: Return Multilevel like ExitLoop(2).

If I need Exit when $event=true (anytime when Func _Sub is on running) It's simple by "If $event Then Exit", but if I need return to mainloop by "If Not _iSleep() Then Return" code is terrible , is there any better way?

$callFunc = True
$event = False

_Main()
Func _Main()
    While 1
        If $callFunc Then _Sub()
    WEnd
EndFunc   ;==>_Main

Func _Sub()
    ConsoleWrite('do work 1' & @CRLF)
    If Not _iSleep(1000) Then Return
    ConsoleWrite('do work 2' & @CRLF)
    If Not _iSleep(2000) Then Return
    ConsoleWrite('do work 6' & @CRLF)
    If Not _iSleep(500) Then Return
    ConsoleWrite('do work 4' & @CRLF)
    If Not _iSleep(3000) Then Return
    ConsoleWrite('do work 2' & @CRLF)
    If Not _iSleep(5000) Then Return
    ConsoleWrite('do work 1' & @CRLF)
    If Not _iSleep(1000) Then Return
    ConsoleWrite('do work 7' & @CRLF)
    If Not _iSleep(500) Then Return
    ConsoleWrite('do work a' & @CRLF)
    If Not _iSleep(10000) Then Return
    ConsoleWrite('do work c' & @CRLF)
    If Not _iSleep(4000) Then Return
    ConsoleWrite('do work g' & @CRLF)
    If Not _iSleep(1000) Then Return
    ;............
EndFunc   ;==>_Sub

Func _iSleep($sleepTime)
    Local $timer = TimerInit()
    While TimerDiff($timer) < $sleepTime
        Sleep(10)
        If $event Then Return False
    WEnd
    Return True
EndFunc   ;==>_iSleep

 

Posted (edited)

Hi,

You can use something like this:

#include <Misc.au3>

$callFunc = True
$event = False

Global $statemachine ,$quit
_Main()
Func _Main()
    While 1
        If $callFunc Then
            _Sub()
            ConsoleWrite ("out" & @crlf)
        EndIf
        If $quit=1 then Return
    WEnd
EndFunc   ;==>_Main

Func _Sub()
    $quit = 0
    $statemachine=0

    While $quit = 0
        Switch $statemachine
            Case 0
                ConsoleWrite('do work 1' & @CRLF)
                _iSleep(1000)
            Case 1

                ConsoleWrite('do work 2' & @CRLF)
                _iSleep(2000)
            Case 2

                ConsoleWrite('do work 6' & @CRLF)
                _iSleep(500)
            Case 3

                ConsoleWrite('do work 4' & @CRLF)
                _iSleep(3000)
            Case 4
                ConsoleWrite('do work 2a' & @CRLF)
                _iSleep(5000)
            Case 5
                ConsoleWrite('do work 1a' & @CRLF)
                _iSleep(1000)
            Case 6
                ConsoleWrite('do work 7' & @CRLF)
                _iSleep(500)
            Case 7
                ConsoleWrite('do work a' & @CRLF)
                _iSleep(10000)
            Case 8
                ConsoleWrite('do work c' & @CRLF)
                _iSleep(4000)
            Case 9
                ConsoleWrite('do work g' & @CRLF)
                _iSleep(1000)
            Case 10
                $statemachine=0
                ;............
        EndSwitch
    WEnd
    $callFunc=0
EndFunc   ;==>_Sub

Func _iSleep($sleepTime)
    Local $timer = TimerInit()
    While TimerDiff($timer) < $sleepTime
        Sleep(10)
        If _isPressed("1b") Then
            $quit = 1
            $statemachine = 1000
            Return False
        EndIf
    WEnd
    $statemachine=$statemachine+1
    Return True
EndFunc   ;==>_iSleep

Of course you can skip the Switch/Endswitch and use

If Not _iSleep(1000) Then Return

as well.

Edited by Dan_555

Some of my script sourcecode

Posted

Another way :

$callFunc = True
$event = False

_Main()
Func _Main()
    While $callFunc
        _Sub()
    WEnd
EndFunc   ;==>_Main

Func _Sub()
    Local $aWork = [[_Work1,1000],[_Work2,2000],[_Work6,500]] ;.....
    For $i = 0 to UBound($aWork) - 1
      $aWork[$i][0]()
      If Not _iSleep($aWork[$i][1]) Then Return
    Next
EndFunc   ;==>_Sub

Func _iSleep($sleepTime)
    Local $timer = TimerInit()
    While TimerDiff($timer) < $sleepTime
        Sleep(10)
        If $event Then Return False
    WEnd
    Return True
EndFunc   ;==>_iSleep

Func _Work1()
  ConsoleWrite ("job1" & @CRLF)
  Return
EndFunc

Func _Work2()
  ConsoleWrite ("job2" & @CRLF)
  Return
EndFunc

Func _Work6()
  ConsoleWrite ("job6" & @CRLF)
  Return
EndFunc

 

Posted

@Dan_555 My _Sub func script is a continuous command in long time, not a switch or short loop did you know, that's problem. If it's a shot loop then I don't care about multi level return because only need few or maybe onetime check return bool value from _iSleep each loop.

Posted

1. Can you give an example on what you need from any other programming language?

2. I think what @Nine has given is an elegant programming style to make for each job a worker function which is dispatched with assigning a function to a variable

Personally I would feel returning multiple nested levels back will make your code hard to maintain and understand.

Even exitloop nn should be used with care

Posted (edited)
#include <Misc.au3>

$callFunc = True
$event = False

Global $quit
_Main()
Func _Main()
    While 1
        If $callFunc Then
            _Sub()
            ConsoleWrite ("out" & @crlf)
        EndIf
        If $quit=1 then Return
    WEnd
EndFunc   ;==>_Main

Func _Sub()
    $quit = 0

    While $quit = 0

    ConsoleWrite('do work 1' & @CRLF)
    If Not _iSleep(1000) Then Return
    ConsoleWrite('do work 2' & @CRLF)
    If Not _iSleep(2000) Then Return
    ConsoleWrite('do work 6' & @CRLF)
    If Not _iSleep(500) Then Return
    ConsoleWrite('do work 4' & @CRLF)
    If Not _iSleep(3000) Then Return
    ConsoleWrite('do work 2' & @CRLF)
    If Not _iSleep(5000) Then Return
    ConsoleWrite('do work 1' & @CRLF)
    If Not _iSleep(1000) Then Return
    ConsoleWrite('do work 7' & @CRLF)
    If Not _iSleep(500) Then Return
    ConsoleWrite('do work a' & @CRLF)
    If Not _iSleep(10000) Then Return
    ConsoleWrite('do work c' & @CRLF)
    If Not _iSleep(4000) Then Return
    ConsoleWrite('do work g' & @CRLF)
    If Not _iSleep(1000) Then Return

    WEnd
    $callFunc=0
EndFunc   ;==>_Sub

Func _iSleep($sleepTime)
    Local $timer = TimerInit()
    While TimerDiff($timer) < $sleepTime
        Sleep(10)
        If _isPressed("1b") Then            ;Check for the escape key.
            $quit = 1           
            Return False
        EndIf
    WEnd
    
    Return True
EndFunc   ;==>_iSleep

As said previously, it works even with your sample code. 

Start it, then press esc, and it jumps out of the two sub's.

Edited by Dan_555
removed the $statemachine refference

Some of my script sourcecode

Posted (edited)
  On 2/11/2021 at 7:08 PM, Dan_555 said:
 

As said previously, it works even with your sample code. 

Start it, then press esc, and it jumps out of the two sub's.

Expand  

Right, that code work but in fact the code is not so few lines, anytime I call _iSleep() I must type "If Not _iSleep() Then Return" - every where every time, so it not ok because _iSleep() using like Sleep and I call it many times in script, if somethings exitst like Return(2) from inside _iSleep(), I can only type _iSleep().

Of course, I think this need comes from the lack of multiprocess, so its not need in other language like C# example.

Edited by zkenjiz
Posted (edited)
  On 2/12/2021 at 8:51 AM, junkew said:

Basic rule of programming:

  • If you feel you are writing the same to frequently probably time to refactor your coding style
    • No multiprocess is not an excuse as you can see in @nine 's answer there is an elegant way to have it handled in a maintainable and understandable way

 

Expand  

I working with AutoIt over 10 years, similar with C# or Java, so I don't thing my coding style is problem here, not all situation can change to using switch or loop sequence, especially in script programming. It's difficult to understand the need here if you are not really in that situation.

Ok, so I thing there's no right answer for finding multi level return like exitloop.

Thanks all!

Edited by zkenjiz

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...