AHK V2: function reference works to class prototype method but not class instance method

Discuss the future of the AutoHotkey language
SAbboushi
Posts: 142
Joined: 08 Dec 2014, 22:13

AHK V2: function reference works to class prototype method but not class instance method

18 Jul 2018, 19:14

I've been trying to dig out of the object/class rabbit hole for weeks now. :crazy: :roll:

Current mystery: the following test has me pondering what I'm missing. Not that I'm looking to code like this, but am wondering why I can create a function reference to a class prototype method, but not to the class instance method that appears to be the exact same func object?

Code: Select all

; To extend a GeekDude example:

MyFunction(this, Param1, Param2)
{
	MsgBox Param1 " has " this.Apples " apples for " Param2 " customers"
}

class MyClassPrototype
{
	Apples := 5
	
	MyMethod(Param1, Param2)
	{
		MsgBox Param1 " has " this.Apples " apples for " Param2 " customers"
	}	
}

MyClass := new MyClassPrototype
MyClass.MyMethod("Johnny", 123)

MyClassPrototype_MyMethod_Addr := &MyClassPrototype.MyMethod
MyClass_MyMethod_Addr := &MyClass.MyMethod ; same address
MyClass_MyMethod_Addr := &MyClass.base.MyMethod ; same address

MyObj := 	{
				;MyMethod: Func("MyFunction"),					; standard function reference
																;	(works fine)
				
				MyMethod: Func("MyClassPrototype.MyMethod"),	; works for class prototype,
																;	but not for class instance:
				;MyMethod: Func("MyClass.MyMethod"),			; doesn't work = empty
				;MyMethod: Func("MyClass.base.MyMethod"),		; doesn't work = empty
				
				MyClassApples: MyClass.Apples, 					; 5
				Apples: 4
			}
MyObj.MyMethod("Johnny", 123)
User avatar
nnnik
Posts: 3527
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: AHK V2: function reference works to class prototype method but not class instance method

19 Jul 2018, 01:18

You cannot get a pointer of data that's inside an array/object by using &.
You need to use .getAdress()
Also in AutoHotkey using & probably does not do what you think it does.
Additionally the func function accepts the name of any function. MyClass.MyMethod is not the name of any function.
Doing MyClass.myMethod will give you the same function object as MyClassPrototype.myMethod because they are the same thing.
Recommends AHK Studio
Helgef
Posts: 3303
Joined: 17 Jul 2016, 01:02
Contact:

Re: AHK V2: function reference works to class prototype method but not class instance method

19 Jul 2018, 01:41

Methods wrote: Methods are stored by reference in the class object.
Meaning, the metod is not stored in the class instance. You should read meta-functions, it describes what happens when you do MyClass.MyMethod, and why it returns the same as MyClassPrototype.MyMethod.

Code: Select all

;MyMethod: Func('MyClass.MyMethod'),			; doesn't work = empty
;MyMethod: Func('MyClass.base.MyMethod'),		; doesn't work = empty
Func wrote: FunctionName
The name of the function whose reference is retrieved.
Obviously, there is no function named MyClass.MyMethod or MyClass.base.MyMethod. The naming convention is not documented as far as I know, which is bad, it should be.
You cannot get a pointer of data that's inside an array/object by using &.
You need to use .getAdress()
getaddress is for getting the address of the string buffer, it cannot be used for a key referring to a number or an object. To get the address of an object stored in another object, &obj.key is fine. MyClassPrototype.MyMethod returns a Func object, the same one as Func('MyClassPrototype.MyMethod'), so &MyClassPrototype.MyMethod == &Func('MyClassPrototype.MyMethod') is true, with both or without any &'s.

Cheers.
SAbboushi
Posts: 142
Joined: 08 Dec 2014, 22:13

Re: AHK V2: function reference works to class prototype method but not class instance method

19 Jul 2018, 17:38

nnnik wrote:You cannot get a pointer of data that's inside an array/object by using &.
You need to use .getAdress()
Thanks. With the caveat that I think .getAddress only gives address for string values

nnnik wrote: Also in AutoHotkey using & probably does not do what you think it does.
I think it's supposed to give me the address of where the contents of a variable are stored. Is that right?
The expressions I used (preceded by "&") return a func object, so I'm expecting to get the address for the func object.
nnnik wrote: Additionally the func function accepts the name of any function. MyClass.MyMethod is not the name of any function.
Makes sense... but still wondering why func function accepts "MyClassPrototype.MyMethod" as a function name?
Helgef wrote:
Methods wrote: Methods are stored by reference in the class object.
Meaning, the metod is not stored in the class instance.
I understand this to mean that within the class object, there is a reference to another object (the method).
But since the base of the class instance is a reference to the class object, I understand that class.method and classInstance.base.method and classInstance.method are all referencing the same object (method)...? It seems to me I must be misunderstanding something here?
Helgef wrote: Obviously, there is no function named MyClass.MyMethod or MyClass.base.MyMethod.
You've both made the same point, so again I seem to be missing something when I find the need to ask
SAbboushi wrote: ... why func function accepts "MyClassPrototype.MyMethod" as a function name?
Helgef wrote:To get the address of an object stored in another object, &obj.key is fine. MyClassPrototype.MyMethod returns a Func object, the same one as Func('MyClassPrototype.MyMethod'), so &MyClassPrototype.MyMethod == &Func('MyClassPrototype.MyMethod') is true, with both or without any &'s.
:headwall: :headwall:
OK - this was my understanding before I posted... and so again...
SAbboushi wrote: ... why func function accepts "MyClassPrototype.MyMethod" as a function name?
Helgef wrote:
Methods wrote:You should read meta-functions, it describes what happens when you do MyClass.MyMethod, and why it returns the same as MyClassPrototype.MyMethod.
I've been looking at that page for weeks now... still having trouble making sense of the logic flow re: "when script gets, sets or calls a key which does not exist within the target object" without examples (which I'm building as my understanding grows thanks in large part to this forum).

For this post though, I believe the relevant outcome is "Search for a matching key [i.e. MyMethod] in the base object's own fields." which I understood before I posted. Is this what you meant? Wondering (specifically) what it was about my post that prompted you to suggest this link? I'm still not seeing what I seem to be missing...!
Helgef wrote: Obviously, there is no function named MyClass.MyMethod or MyClass.base.MyMethod. The naming convention is not documented as far as I know, which is bad, it should be.
The naming convention of...?
coffee
Posts: 78
Joined: 01 Apr 2017, 07:55

Re: AHK V2: function reference works to class prototype method but not class instance method

19 Jul 2018, 21:19

Makes sense... but still wondering why func function accepts "MyClassPrototype.MyMethod" as a function name?
Skimming the source (correct me if i'm wrong), because "MyClassPrototype.MyMethod" is the name of the function internally (so there may be a function named that way). Func relies internally on FindFunc. FindFunc relies on the name set by DefineFunc. DefineFunc sets the name of the function if it's a method definition as "CLASSNAME.FUNCTIONNAME".
lexikos
Posts: 6207
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: AHK V2: function reference works to class prototype method but not class instance method

19 Jul 2018, 22:49

There is only one MyClassPrototype.MyMethod, not one instance of the method for each instance of the object. Putting aside addresses, MyClass.MyMethod will give you a function object which is in no way associated with an instance. To call it, you would need to pass the instance, e.g. .Call(MyClass, "Johnny", 123).

If you call ListVars while the method is running, it will show the full function name. The format of the name is not in any way documented, so it would be foolish to rely on this. There is generally no good reason to do so, since you can reference the method via the class object. That you can also reference it by name (string) is merely a side-effect of the implementation.
You cannot get a pointer of data that's inside an array/object by using &.
That is irrelevant. The script is retrieving the address of a function object. The addresses are the same because they are all references to the same object.
Helgef
Posts: 3303
Joined: 17 Jul 2016, 01:02
Contact:

Re: AHK V2: function reference works to class prototype method but not class instance method

20 Jul 2018, 02:06

still wondering why func function accepts "MyClassPrototype.MyMethod" as a function name?
Because that is the name of course, it is not a quoted expression. Another way to realise that is to do,

Code: Select all

msgbox a.b.name '`n' (new a).b.name '`n' func('a.b').name
class a{
	b(){
	}
}
Additionally, a_thisfunc will show you the name.

Code: Select all

a.b()
(new a).b()
class a{
	b(){
		msgbox a_thisfunc
	}
}

I've been looking at that page for weeks now... still having trouble making sense of the logic flow re: "when script gets, sets or calls a key which does not exist within the target object" without examples
You can get the Func object via the expression MyClass.MyMethod, but MyMethod is not stored in MyClass, you can realise by asking MyClass.haskey('MyMethod'), so when you try to get MyMethod with MyClass.MyMethod, is not found in MyClass, instead, as per the link I provided, it is searched for in MyClass.base, which is equal to MyClassPrototype and there it is found, again, ask haskey. If MyClassPrototype had defined the meta function __get, this method would have been called before searching for MyMethod in MyClassPrototype.
DefineFunc sets the name of the function if it's a method definition as "CLASSNAME.FUNCTIONNAME".
More generally, it will be "CLASSNAME.NESTEDCLASS...FUNCTIONNAME".
There is generally no good reason to do so, since you can reference the method via the class object. That you can also reference it by name (string) is merely a side-effect of the implementation.
I would probably not miss this feature, I've seen other use it though. I think it should be documented or removed, when v2 is done.

Cheers.
User avatar
nnnik
Posts: 3527
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: AHK V2: function reference works to class prototype method but not class instance method

20 Jul 2018, 02:47

You should try to make a function that can turn any object into a string. It will help you see what's inside the object and what's inside its base.
Also having something you can see greatly simplifies memorizing and strengthening the things you have already learned.
If you've been stuck at that point for so long I would also recommend taking a break and learning something different before returning to objects.
Recommends AHK Studio
SAbboushi
Posts: 142
Joined: 08 Dec 2014, 22:13

Re: AHK V2: function reference works to class prototype method but not class instance method

20 Jul 2018, 19:56

Thank you VERY much for all the explanations and examples. Very helpful.

Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 2 guests