Why nested class methods don't receive "this" object reference from parent class? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 05:33

Hello guys,

I was a little surprised by this behavior.

Code: Select all

obj := new parent
obj.child.method()

return

class parent
{
	__new()
	{
		this.var1 := "MERDA"
	}
	class child
	{
		method()
		{
			msgbox, % this.var1 ; shows nothing.
		}
	}
}
For flexibility reasons I was expecting "method" to receive the object reference he is called on, but it didn't work. It's the first time I use nested classes and I had the intention to use them for some helper methods to be called statically on an instance of the parent class.

Any hints on how to fix this?
ABCza on the old forum.
My GitHub.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 05:45

Code: Select all

class child extends parent
nevermind, this doesnt work
Last edited by swagfag on 07 Feb 2019, 06:00, edited 1 time in total.
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 06:00

swagfag wrote:
07 Feb 2019, 05:45

Code: Select all

class child extends parent
It makes sense if I think that I need to manipulate the parent object and I evaluated this solution already. My only concern is that I have already a lot of code and this change would need to rethink most of it.
ABCza on the old forum.
My GitHub.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 06:03

For flexibility reasons I was expecting "method" to receive the object reference he is called on
As documented, it does. The invoking object is parent.child though. You can pass this explicitly by obj.method.call(obj).
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 06:05

Code: Select all

#Warn ClassOverwrite

obj := new parent
obj.child.method()

return

class parent
{
	__new()
	{
		this.var1 := "MERDA"
		this.child := new parent.child(this)
	}

	class child
	{
		__New(reference_to_parent) {
			this.parent := reference_to_parent
		}

		method()
		{
			msgbox, % this.parent.var1 ; shows nothing.
		}
	}
}
very roundabout way of doing it though
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 06:24

Classes are just objects - the way you called it probably passed the child class into the this parameter.
Keep in mind that static methods are a thing.
Recommends AHK Studio
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 06:46

Helgef wrote:Just note that that will cause a circular reference.
ahh.. true. then:

Code: Select all

#Warn ClassOverwrite

obj := new parent
obj.child.method()

return

class parent
{
	__new()
	{
		this.var1 := "MERDA"
		this.child := new parent.child(&this)
	}

	class child
	{
		__New(ptr_parent) {
			this.ptr_parent := ptr_parent
		}

		method()
		{
			msgbox, % Object(this.ptr_parent).var1 ; shows nothing.
		}
	}
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 07:13

In general, it is better to have a method to clear the circular reference imo, doing &this without calling objaddref can be dangerous and is against the recommendation in the docs.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 09:36

yes, its bad, but having to call the additional method to clear it is inconvenient

use the proxy i guess: https://www.autohotkey.com/boards/viewtopic.php?p=175700#p175700
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Re: Why nested class methods don't receive "this" object reference from parent class?

07 Feb 2019, 19:47

Helgef wrote:
07 Feb 2019, 06:03
For flexibility reasons I was expecting "method" to receive the object reference he is called on
As documented, it does. The invoking object is parent.child though. You can pass this explicitly by obj.method.call(obj).

But in this specific case the invoking object is "obj". I would agree instead If I called "parent.child.method()". Thank you for the hint about method.Call :thumbup:

swagfag wrote:
07 Feb 2019, 06:05

Code: Select all

#Warn ClassOverwrite

obj := new parent
obj.child.method()

return

class parent
{
	__new()
	{
		this.var1 := "MERDA"
		this.child := new parent.child(this)
	}

	class child
	{
		__New(reference_to_parent) {
			this.parent := reference_to_parent
		}

		method()
		{
			msgbox, % this.parent.var1 ; shows nothing.
		}
	}
}
very roundabout way of doing it though

Nice one, although I need to create an instance of the child class. Anyway I can live with the circular reference and manage it in my clean-up function :geek: :thumbup:

nnnik wrote:
07 Feb 2019, 06:24
Classes are just objects - the way you called it probably passed the child class into the this parameter.
Keep in mind that static methods are a thing.

Yeah I realized that after some tries. Still, I find it a little odd, being the invoking object "obj".
ABCza on the old forum.
My GitHub.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Why nested class methods don't receive "this" object reference from parent class?

08 Feb 2019, 01:34

parent.child is the invoking object. What do you you expect obj.child to return? obj? No, you expect to get parent.child, and you do. So obj.child.method is parent.child.method, which is (parent.child).method.

Cheers.
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Re: Why nested class methods don't receive "this" object reference from parent class?

08 Feb 2019, 05:29

Helgef wrote:
08 Feb 2019, 01:34
parent.child is the invoking object. What do you you expect obj.child to return? obj? No, you expect to get parent.child, and you do. So obj.child.method is parent.child.method, which is (parent.child).method.

Cheers.

Your point is clear, I got what the actual implementation is. I was questioning the logic though because "semantically" the calling object is obj.

Cheers! :beer:
ABCza on the old forum.
My GitHub.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Why nested class methods don't receive "this" object reference from parent class?

08 Feb 2019, 06:52

Instead of explicitly passing the object to the parameter this by using call, you can define your own this-parameter, for example,

Code: Select all

global obj := new C
obj.S.method1(obj) ; pass the invoking object, avoiding .call()

class C {
	class S {
		method1(self){
			; 'this' refers to C.S
			msgbox % self == obj
		}
	}
}
I think that is the simplest and clearest way to do it. Edit, but I would probably call it like C.S.method1(obj)
You can also implement __call, eg,

Code: Select all

global obj := new C
obj.method1()

class C {
	class S {
		method1(){
			; no parameter refers to C.S
			msgbox % this == obj
		}
	}
	__call(m, p*){
		if (C.S.haskey(m))	; you can not call a in C, which has the same name as one in C.S
			return C.S[m].call(this, p*)
	}	
}
This is also simple.

Cheers.
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Re: Why nested class methods don't receive "this" object reference from parent class?

08 Feb 2019, 09:49

Yes, I agree about the simplest way. But it's not interesting :D

The solution with __Call I don't like it, because it implies calling the inner class method on the outer class object.

I found that calling the inner class uses __Get, so this is what I got now:

Code: Select all

global obj := new C
obj.S.method1()

return

class C {
	Static iObj

	__New()
	{
		this.var := "OH SHIT!"
	}

	__Get( aName )
	{
		If ( aName == "S" )
			 C.iObj := this
	}

	class S {
		method1(){
			msgbox % C.iObj.var
		}
	}
}
ABCza on the old forum.
My GitHub.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Why nested class methods don't receive "this" object reference from parent class?

08 Feb 2019, 10:22

while creative, that is very dangerous. Consider what can happen if there is an interruption.

Cheers.
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Re: Why nested class methods don't receive "this" object reference from parent class?

08 Feb 2019, 11:19

Helgef wrote:
08 Feb 2019, 10:22
while creative, that is very dangerous. Consider what can happen if there is an interruption.

Cheers.
I guess the added reference could be managed in the __Delete method. Or are you referring to something else?

Cheers!
ABCza on the old forum.
My GitHub.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Why nested class methods don't receive "this" object reference from parent class?

08 Feb 2019, 11:32

I mean that an interruption can change the object referenced to by C.iObj, while a method referencing it still executes.
User avatar
cyruz
Posts: 346
Joined: 30 Sep 2013, 13:31

Re: Why nested class methods don't receive "this" object reference from parent class?  Topic is solved

08 Feb 2019, 11:35

Yeah seems kinda unreliable.

What about this then:

Code: Select all

global obj := new C
obj.S.method1()

return

class C {
	__New() {
		this.var := "OH SHIT!"
	}

	__Get( aName ) {
		If ( aName == "S" )
			Return new C.S(this)
	}

	class S {
		__New(outer) {
			this.outer := outer
		}

		method1() {
			msgbox % this.outer.var
		}
	}
}
Last edited by cyruz on 09 Feb 2019, 09:29, edited 2 times in total.
ABCza on the old forum.
My GitHub.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: prototype_zero and 317 guests