For non-integer keys (or more precisely, the superset of all keys, which may include integers), the only way I could think of to get a custom enumerator to work is to enumerate all keys to a list in a for-loop in the __new() of the object returned by _newenum(). Then, in next(), just navigate through the list of keys and call the next one. For large dictionaries, this doesn't seem like a good practice... enumerating all keys just to get to the first. I'm sure there's a better way, and I'm hoping someone can point me in the right direction.
I thought about maybe having a shadow enumerator (of the standard type) created in the __new() of the enumerator class, by calling .base._newenum(). Then maybe in my custom next(), I could just call that shadow enumerator's next and alter the output from there before I return. I wasn't able to get that to work.
I've tried to boil it down to the simplest case, below. I have a base iterable class that defines _newenum() as returning an object of enumerator class. Let's say the only transform I want to do is to change my custom next() to make the value (not the key) return if only one byref parameter is passed. That would enable the syntax for itm in collection rather than requiring for key, itm in collection. In the standard behavior, if you supply one variable, you get the key not the value. (I'm not saying that my custom enumerator is a better treatment... only that it's a simple example of something I could do to alter the standard enumerator behavior for not-necessarily-numerical keys.)
I think I can figure out my more complicated customizations if you can help me just solve this one:
Code: Select all
class itr extends obj { ; iterable base class
_newenum() {
return new enm(this)
}
}
class enm { ; enumerator base class
__new(itr) { ; will work for any iterable
this.itr := itr
}
next(byref var1, byref var2:="") {
; I want this to return val (not key) if only var1 is specified
; or key, val if two vars are specified.
}
}