is this correct behaviour of procedurereturn in a foreach ?

Just starting out? Need help? Post your questions and find answers here.
sculptor
User
User
Posts: 16
Joined: Sun Mar 01, 2009 10:11 pm
Location: uk

is this correct behaviour of procedurereturn in a foreach ?

Post 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
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: is this correct behaviour of procedurereturn in a foreac

Post 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
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
sculptor
User
User
Posts: 16
Joined: Sun Mar 01, 2009 10:11 pm
Location: uk

Re: is this correct behaviour of procedurereturn in a foreac

Post by sculptor »

Thanks for the info collectordave
User avatar
skywalk
Addict
Addict
Posts: 4241
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: is this correct behaviour of procedurereturn in a foreac

Post by skywalk »

Much easier if you use EnableExplicit and post working code. :idea:
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: is this correct behaviour of procedurereturn in a foreac

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
Demivec
Addict
Addict
Posts: 4281
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: is this correct behaviour of procedurereturn in a foreac

Post 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.
sculptor
User
User
Posts: 16
Joined: Sun Mar 01, 2009 10:11 pm
Location: uk

Re: is this correct behaviour of procedurereturn in a foreac

Post 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. :oops:

Thanks again for your wonderfully quick responses.
Post Reply