BlitzMax NG Reflection EnumMethods() list order

Started by TomToad, February 27, 2020, 09:26:17

Previous topic - Next topic

TomToad

I am just wondering when using reflection if EnumMethods() is guaranteed to always return the methods in the order it was declared.  I tried out a test example:
Code: BASIC
SuperStrict

Type TTest
Method M_axz()
Print "First"
End Method

Method M_dlk()
Print "Second"
End Method

Method M_bmx()
Print "Third"
End Method

Method M_abc()
Print "Fourth"
End Method
End Type

Local Test:TTest = New TTest

Local id:TTypeId = TTypeId.ForObject(Test)

For Local m:TMethod = EachIn id.EnumMethods()
If m.Name()[..2] = "M_" Then m.invoke Test
Next


This shows the methods being returned in the correct order.  But what happens when I add methods?  Say 20 of them or 50?  Are there circumstances when the method list might return a different order?  Or is it guaranteed to be in creation order?

------------------------------------------------
8 rabbits equals 1 rabbyte.

Derron

For now (it depends on reflection.mod - and its implementation) they are added to a TList in the order of the source file.

So an extended type will have the methods of the "parent" before.


BTW: If you directly request a method (by its name) it is using a string map for faster lookup.


bye
Ron

TomToad

Thanks.  Hopefully it will remain this way in future versions. 

I was just adding functions to a big Select/Case clause, which was getting a bit cumbersome as I added more functions.  Select Page Case 1 Func1 Case 2 Func2 etc...  Then defining hot keys to jump directly to a page, If KeyHit(KEY_A) then Page = 1; If KeyHit(KEY_B) then page = 2; if Keyhit(KEY_RIGHT) then Page :+ 1. etc...

Then I briefly thought about creating a helper where you would "register" functions, similar to MFC or OWL, but then I thought, why not let reflection handle it?  I just create a new method and it gets automagically added to the list.  Figured I could encode hotkey and page number in the method name, such as P_1_A_Intro() would be page 1, hotkey A.  But I quickly realized the problem with that.  If I decided later I needed to add 3 more pages between 5 and 6, then I would need to rename every method from P_6... on up.  Hence, the question about method order.  If order is guaranteed, then to add three pages is as simple as inserting three new methods between two.
------------------------------------------------
8 rabbits equals 1 rabbyte.

Derron

I have been doing the "register function" thing in the past.

Reflection stuff is populated during startup, so it is not too costly - especially if you wait for a keyhit before :)


@ remain this way
Hmm, in 2018 Brucey was changing it by introducing TStringMap - but I successfully brought back "the order".
Reflection was "discussed" to get redone in a later stage but this idea seems to be not tackled in the next foreseeable future.


bye
Ron

TomToad

Been doing some more experimentation.  WIth reflection, I am able to read in the methods of an extended type and call the methods.  TO do this without reflection means that I would need to make the methods abstract, which requires knowing the number of methods  and name of each ahead of time.

I'm sure there is a speed tradeoff for doing thimgs this way, but for my purpose, I don't need super fast.
Code: blitzmax
SuperStrict
Type TTest
Method Run()
Local id:TTypeId = TTypeId.ForObject(Self)
For Local m:TMethod = EachIn id.EnumMethods()
Print m.Name()
If m.name() <> "New" And m.name() <> "Run" Then m.invoke Self
Next
End Method
End Type

Type TExtended Extends TTest
Method abc()
Print "I'm in abc"
End Method

Method xyz()
Print "I'm in xyz"
End Method

Method jkl()
Print "I'm in jkl"
End Method
End Type

Local Me:TExtended = New TExtended
Me.Run

------------------------------------------------
8 rabbits equals 1 rabbyte.

Derron

You could cache "id" and "enummethods()" results ... so on each run you just iterate over the given TMethod array.

bye
Ron