Custom iterator

What I am trying to do is iterate a collection of OleObjects using MoveFirst, MoveNext functions provided by an Ole application. What I would like to avoid is having to cache values in a Xojo array, collection or dictionary, as the collection may change dynamically albeit not too quickly.

Strikes me as a For…Each job with a custom iterator. Sadly when I looked at the Iterator, Iterable interface documentation it does not appear to have received much love from Xojo. I followed a blog post on creating an iterator which told me what to do but not why I was doing it. As I am not trying to iterate a simple array I am hardly the wiser.

Just wondering if anyone can kick me in the right direction.

oh probably can

the point of foreach is that it takes an Iterable object and by using its movement methods can walk through what ever that iterator returns

for instance, in Xojo arrays are iterable
so when you use foreach on an array it

  1. gets the iterator
  2. repeatedly calls MoveNext until no more items are returned

I’ll see if I can put together an example

1 Like
Class1 implements Iterable

Public Sub Constructor()
  For i As Integer = 0 To 10
    mitems.append 100 - i
End Sub

Public Function Iterator() As Class2
  // Part of the Iterable interface.
  return new Class2(self)
End Function

Public Property mitems() As integer
Class2 Implements Iterator

Public Function MoveNext() As Boolean
  // Part of the Iterator interface.
  mCurrent = mCurrent + 1
  return mCurrent < mValueProvider.mitems.LastIndex
End Function

Public Function Value() As Variant
  // Part of the Iterator interface.
  Return mValueProvider.mitems(mCurrent)
End Function

Public Sub Constructor(valueProvider as Class1)
  mValueProvider = valueProvider
  mCurrent = -1
End Sub

Protected Property mCurrent As Integer
Protected Property mValueProvider As Class1

test code

Dim c As New class1

For Each i As Integer In C
  System.DebugLog i.ToString

Note there are MANY issues with the little example (ie the iterator itself would be something you could call new on and pass the right parts, that shouldnt be possible, the property that the iterator uses is public and it should probably be protected at least etc)

OK so whats going on

In the test code when the FOR EACH is encounter since C is ITERABLE

  1. the Iterator method of the instance is called
  2. the instance creates the iterator and returns it to the FOR code
  3. the FOR EACH code checks to see if it can MOVE NEXT by calling the ITERATORS “MoveNext” method
  4. if TRUE the Iterators VALUE method is called and
  5. main body of the loop is entered and the SYSTEM.DEbugLog line is executed and the value is printed

I inserted BREAK statements in those code paths so you can step into each and see how things progress

1 Like

OH !!!
I used 2024r2 for this

Older versions have a different API for Iterable and Iterator and MAY NOT work because they return Object (not Auto or Variant)

2023r1.1 is like this

Much appreciated Norman.

Little tied up responding to proposals but will take a look when I have time to digest it. Skim reading the explaination is certainly more comprehensible than what I have seen so far.