Page 1 of 1
is this correct behaviour of procedurereturn in a foreach ?
Posted: Mon Jul 29, 2019 3:26 am
by sculptor
Hi, could somebody explain why when i do a procedurereturn from inside a foreach over a list. The second time i call the procedure it seems to have remembered where i was in the list instead of starting the foreach loop again. So i had to put in the resetlist to correct it.
It's a kind of nooby question because i have been a long time away from purebasic. But it took me a long time to find the problem in my code.
Code: Select all
Procedure.i find_the_word(word.s);word is passed from a different list, foreach
Protected tmp.i = 0
ForEach dict_contents() ;loop thru a global dictionary of words (i would have thought the foreach would set back to element 0)
tmp.i + 1
If dict_contents() = word.s ;is the word in the dict?
Debug tmp.i ; here on the second call to the procedure list element has been remembered
ResetList(dict_contents()) ; so unless i do this reset i have the wrong count in tmp
ProcedureReturn tmp.i
EndIf
Next
Debug "tmp here is= " + tmp
ProcedureReturn 0
EndProcedure
Re: is this correct behaviour of procedurereturn in a foreac
Posted: Mon Jul 29, 2019 3:50 am
by collectordave
That is the way lists behave.
I imagine a list is like a shopping list with a little arrow next to the item in the list you are looking at, it is up to you to move that arrow. You have the list declared as Global so the arrow can be moved anywhere in your programme.
If you use ResetList(dict_contents()) before the ForEach it should be Ok.
collectordave
Re: is this correct behaviour of procedurereturn in a foreac
Posted: Mon Jul 29, 2019 3:58 am
by sculptor
Thanks for the info collectordave
Re: is this correct behaviour of procedurereturn in a foreac
Posted: Mon Jul 29, 2019 4:07 am
by skywalk
Much easier if you use EnableExplicit and post working code.

Re: is this correct behaviour of procedurereturn in a foreac
Posted: Mon Jul 29, 2019 5:03 am
by nco2k
collectordave wrote:If you use ResetList(dict_contents()) before the ForEach it should be Ok.
you dont have to use ResetList() because ForEach already resets the list.
@sculptor
i cannot reproduce your issue. its hard to help without a working example that showcases your problem.
c ya,
nco2k
Re: is this correct behaviour of procedurereturn in a foreac
Posted: Mon Jul 29, 2019 5:35 am
by Demivec
@sculptor: I cannot reproduce your issue. Here is the sample code I used with the line that contains ResetList() commented out:
Code: Select all
EnableExplicit
Global NewList dict_contents.s()
Define h, i, j, k
#ASCII_A = 'A'
#ASCII_Z = 'Z'
;fill list with 456976 4 letter words "AAAA" through "ZZZZ"
For h = #ASCII_A To #ASCII_Z
For i = #ASCII_A To #ASCII_Z
For j = #ASCII_A To #ASCII_Z
For k = #ASCII_A To #ASCII_Z
AddElement(dict_contents())
dict_contents() = Chr(h) + Chr(i) + Chr(j) + Chr(k)
Next
Next
Next
Next
Procedure.i find_the_word(word.s);word is passed from a different list, foreach
Protected tmp.i = 0
ForEach dict_contents() ;loop thru a global dictionary of words (i would have thought the foreach would set back to element 0)
tmp.i + 1
If dict_contents() = word.s ;is the word in the dict?
Debug tmp.i ; here on the second call to the procedure list element has been remembered
;ResetList(dict_contents()) ; so unless i do this reset i have the wrong count in tmp
ProcedureReturn tmp.i
EndIf
Next
Debug "tmp here is= " + tmp
ProcedureReturn 0
EndProcedure
Define a$
Repeat
;generate random 4 letter word
a$ = Chr(Random(#ASCII_Z, #ASCII_A)) +
Chr(Random(#ASCII_Z, #ASCII_A)) +
Chr(Random(#ASCII_Z, #ASCII_A)) +
Chr(Random(#ASCII_Z, #ASCII_A))
Debug a$
Debug "---result of search 1: " + find_the_word(a$)
Debug "---result of search 2: " + find_the_word(a$)
Debug "---result of search 3: " + find_the_word(a$)
a$ = InputRequester("", "Press Enter to repeat, Q to quit.", "")
Until a$ = "Q" Or a$ = "q"
The test code creates a list of 456976 unique words. If a previous list position was used in the procedure than it would never find the word in additional searches. It produces consistent results as is.
The lines you have documented with "here on the second call to the procedure list element has been remembered", will only be reached if a match is found and so will always contain the same element out of a set of unique elements. Your conclusion that this is somehow evidence of buggy behavior is incorrect.
Re: is this correct behaviour of procedurereturn in a foreac
Posted: Mon Jul 29, 2019 7:51 am
by sculptor
Thank you all for your replies which made me go back again and look at my code.
It turned out to be one of those horrible self inflicted bugs, I was loading the dictionary repeatedly which caused the list to keep growing.
By putting a resetlist() in this procedure it appeared to fix the problem.
Thanks again for your wonderfully quick responses.