Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-06

How to find the return type of a for..in ?

8 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

I've never really used the for..in in real code, because I think the iterator is very limited. I've implemented much more flexible iterators for most container types.

Here is another stumbling block of for.in usage. The statement itself doesn't give you any hint as to what the return type is. What is the correct way of finding the return type of a for..in statement? I need to define a variable of some or other type. The container's Iterate() method doesn't give any hints. Neither does the container's GetEnumerator() method. I then had to dig into the source code of the return type of GetEnumerator() to finally find the Current property and it's return type.

And before you say it, the for..in return type is not always very obvious. eg: if you use for..in over a TJSONObject the return type is not TJSONData, but rather TJSONEnum. And as that name [badly] suggests, it isn't actually an enum (as per the Object Pascal language definition). It is in fact a Record structure.

Regards,
Graeme

Reply by email

Graeme Geldenhuys
to Mattias Gaertner
Mattias Gaertner wrote
Have you seen this page:

Yes, that's what I looked at to see how to use for..in but nowhere does it mention or give a JSON example. Granted, I haven't read every single word on that page, but a lot seem to cover how to implement an iterator for your own containers so for..in loops can work with it. This was not what I was looking for.

The fpjson unit already supports the for..in loop, I just didn't know [immediately obvious] what data type the loop variable must be - hence my question.

So it seems the only way to use for..in on moderate to complex objects [that you haven't looped before], is to delve into the source code and see how the enumerator class was implemented, and there you will find the loop variable type to use.

Regards,
Graeme

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 17 lines
On 2016-06-16 15:29, Mattias Gaertner wrote: > Have you seen this page: Yes, that's what I looked at to see how to use for..in but nowhere does it mention or give a JSON example. Granted, I haven't read every single word on that page, but a lot seem to cover how to implement an iterator for your own containers so for..in loops can work with it. This was not what I was looking for. The fpjson unit already supports the for..in loop, I just didn't know [immediately obvious] what data type the loop variable must be - hence my question. So it seems the only way to use for..in on moderate to complex objects [that you haven't looped before], is to delve into the source code and see how the enumerator class was implemented, and there you will find the loop variable type to use.

The return type of the GetEnumerator function tells you what the class is.

It is a good idea for a Lazarus IDE extension.

Michael.

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt
Michael Van Canneyt wrote
The return type of the GetEnumerator function tells you what the class is.

Actually, not quite. In the case of TJSONObject, it returns a base type enumerator: TBaseJSONEnumerator

But if you look at the actual code of TJSONObject.GetEnumerator(), then
you will notice that the actual type returned is TJSONObjectEnumerator.

So by simply looking at the TJSONObject class interface you don't know the real type. Yes you could of course query it, but the return type is not obvious until you look at the actual implementation.

It is a good idea for a Lazarus IDE extension.

Yes, I would imagine some IDE magic to code complete a for..in statement would be quite useful. But then is also shows how badly designed (again thanks to Delphi) the for..in statement is. It's not very friendly without "IDE magic".

Regards,
Graeme

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 20 lines
On 2016-06-16 16:49, Michael Van Canneyt wrote: > The return type of the GetEnumerator function tells you what the class is. Actually, not quite. In the case of TJSONObject, it returns a base type enumerator: TBaseJSONEnumerator But if you look at the actual code of TJSONObject.GetEnumerator(), then you will notice that the actual type returned is TJSONObjectEnumerator. So by simply looking at the TJSONObject class interface you don't know the real type. Yes you could of course query it, but the return type is not obvious until you look at the actual implementation. > It is a good idea for a Lazarus IDE extension. Yes, I would imagine some IDE magic to code complete a for..in statement would be quite useful. But then is also shows how badly designed (again thanks to Delphi) the for..in statement is. It's not very friendly without "IDE magic".

Since the enumerator is an interface/class: you will never know what is instantiated. You will only know the top-level 'declared' class.

Michael.

Reply by email