Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum
Derar
Novice


Joined: 09 Sep 2006
Posts: 44

PostPosted: Mon Aug 02, 2010 7:32 pm   

[3.22] #FORALL, %ismember, and %del(n)item... internal indexing issue?
 
So I try not to say "bug" unless I feel like I can point to what exactly I think is causing it.

Frankly, this stumps me completely.

Code:

<var name="TestSorted" type="StringList" copy="yes">
  <value>20|12|10|10|10|5|5|2</value>
  <json>[20,12,10,10,10,5,5,2]</json>
</var>
<var name="TestList" type="StringList" copy="yes">
  <value>10|10|2|20|5|12|10|5</value>
  <json>[10,10,2,20,5,12,10,5]</json>
</var>

<alias name="RunTest" copy="yes">
  <value>
    $sorted = %1
    $unsorted = %2

    #SHOW "$sorted: " %json($sorted)
    #SHOW "$unsorted: " %json($unsorted)

    #FORALL ($sorted) {
      $pos = %ismember(%repeatnum, $unsorted)
      #SHOW %repeatnum " is " $pos " in " %json($unsorted)
      $unsorted = %delnitem($unsorted, $pos)
      }
  </value>
</alias>


Execute: RunTest @TestSorted @TestList
Output:
Code:

$sorted:  [20,12,10,10,10,5,5,2]
$unsorted:  [10,10,2,20,5,12,10,5]
20  is  4  in  [10,10,2,20,5,12,10,5]
12  is  5  in  [10,10,2,5,12,10,5]
10  is  1  in  [10,10,2,5,10,5]
10  is  1  in  [10,2,5,10,5]
10  is  1  in  [2,5,10,5]
5  is  1  in  [5,10,5]
5  is  1  in  [10,5]
2  is  0  in  [5]


Now, if you're missing it, the third time it hits 10, the whole thing flies off the handle because %ismember stops returning the correct index. This is the simplest posting example of what happens, but I've done some other testing with it as well, such as...

- Using all string values instead of number values. Result is the same.
- Echoing a raw %ismember in the loop to see if $pos just got stuck; the %ismember matches the $pos output
- Using %delitem(%repeatnum, $unsorted) instead of %delnitem($unsorted, $pos); same result.
- Changing the order of the unsorted list, or removing the tripled value of 10 (went to 30|20|12|10|10|5|5|2); still started screwing up after a few iterations
- Using the actual variables in the loop instead of local copies; same result

Now, what does make it work, is creating my own ismember function and substituting it in place of %ismember in the alias loop:

Code:

<func name="_ismember" id="5">
  <value>
    $item = %1
    $list = %2

    #RETURN %ismember($item, $list)
  </value>
</func>


Running it then outputs properly:
Code:

$sorted:  [20,12,10,10,10,5,5,2]
$unsorted:  [10,10,2,20,5,12,10,5]
20  is  4  in  [10,10,2,20,5,12,10,5]
12  is  5  in  [10,10,2,5,12,10,5]
10  is  1  in  [10,10,2,5,10,5]
10  is  1  in  [10,2,5,10,5]
10  is  3  in  [2,5,10,5]
5  is  2  in  [2,5,5]
5  is  2  in  [2,5]
2  is  1  in  [2]


So it seems like somewhere in there, the delete item call screws up and I guess doesn't update the list index properly? But passing the list out to a user function to obtain the value creates a list copy with a proper index, I guess.

But... something's not right. :)
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Aug 03, 2010 4:52 pm   
 
Yep, definitely a bug somewhere. As you say, it looks like the internal index isn't getting updated properly by %delnitem.

The reason your user function works is that CMUD is making a copy of the lists (when you assign $item=%1) and that causes CMUD to recompute the internal index cache for $item.

Added to bug list. Good catch!

P.S. Thanks for the excellent procedure for reproducing this. This is a very good example of an excellent bug report.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net