Weird compile error: Illegal EachIn expression
BlitzMax Forums/BlitzMax Programming/Weird compile error: Illegal EachIn expression
| ||
I get that compile error when attempting to run this:For Local t$=EachIn hash.ObjectEnumerator() Print t Next While this compiles fine and works as expected: For Local t$=EachIn hash Print t Next What's going on? Here's the rest of the code. |
| ||
I believe ObjectEnumerator() is a "private" method which implements the enumeration stuff, but which you don't use yourself. When you use Eachin, BlitzMax expects the argument to be of a certain structure - either an array or an Object which has the enumeration functionality. |
| ||
To put it another way: EachIn calls ObjectEnumerator on the object passed as collection. If you call ObjectEnumerator yourself, you're no longer passing a collection that can be enumerated by EachIn (unless you work some naughtiness so that your enumerator is also a collection, which is conceptually just plain wrong); the thing you're passing has the wrong structure for what EachIn expects to do with it (but you don't get a type error because this is implemented separately from type checking; in Monkey you would presumably get a type error indicating the wrong interface). It's a type error, with a weird message. An enumerator is not a collection. Analogous situation: say you have a function that returns the width of an image prepended with "Foo": Strict Function Foopify:String(img:TImage) Return "Foo " + ImageWidth(img) End Function Local img:TImage = CreateImage(256, 256) Print Foopify(img) ' Fine, prints "Foo 256" Print Foopify(ImageWidth(img)) ' Type error: we need a TImage, not a number By trying to do one step of the internal process yourself, you change the type of the value and render the whole thing invalid. BlitzMax doesn't actually call it a type error because its type system doesn't include interfaces, but it is the same thing. |
| ||
How do the functions which return iterators such as MapKeys work, then? And the error isn't isolated to the ObjectEnumerator method, the error also occurs when trying to use NodeEnumerator, which is the one I was really expecting to use. And I've written similar code in the past that worked without issue. This code executes without any error and runs as expected: Import pine.HashTable Local hash:HashTable=CreateHash(32) HashInsert hash,"foo","bar" For Local s$=EachIn hash.ObjectEnumerator() Print s Next And the pine.HashTable module is available here, for any relevant code: http://blitzbasic.com/Community/post.php?topic=97992&post=1141947 I'm only trying to reproduce the same basic thing that I did before, and I'm not sure what's different about the enumeration code. |
| ||
Okay, I found the issue. It was a very easy fix. I merely added this to my hash2denum type: Method ObjectEnumerator:hash2denum() Return Self End Method |