base.method() and this.base.method() Confusion

Get help with using AutoHotkey and its commands and hotkeys
A_User
Posts: 36
Joined: 21 Aug 2017, 01:15

base.method() and this.base.method() Confusion

23 Nov 2017, 06:13

Hi,

Can somebody explain why the following code shows the message box three times? I expected twice.

Code: Select all

_o := new BaseKeyword2 ; shows the message box 3 times, not twice

class BaseKeyword {
    
    __New( s ) {
        msgbox % s
    }   
    
}
class BaseKeyword2 extends BaseKeyword {
    __New() {
        base.__New( "a" )
        this.base.__New( "b" )
    }    
}
A_AhkUser
Posts: 1076
Joined: 06 Mar 2017, 16:18
GitHub: AAhkUser
Location: France

Re: base.method() and this.base.method() Confusion

23 Nov 2017, 10:04

Hi A_User,

Because base is a key: MyObject.key

Code: Select all

MyObject := {base: {__New:Func("test")}, key:7, method:Func("m")}
(o:=new MyObject).method()

test(this) {
MsgBox % this.key
}
m(this) {
MsgBox % A_ThisFunc
}
A_User
Posts: 36
Joined: 21 Aug 2017, 01:15

Re: base.method() and this.base.method() Confusion

23 Nov 2017, 10:56

Hi,

I don't find your reply answering why the code I posted shows the message box three times.

It seems the constructor of the extended class is called twice. The strange part is that if you comment out `base.__New( "a" )`, the message box shows only once.
A_AhkUser
Posts: 1076
Joined: 06 Mar 2017, 16:18
GitHub: AAhkUser
Location: France

Re: base.method() and this.base.method() Confusion

23 Nov 2017, 12:30

__Init is call only once. base.__New( "a" ) amounts to call BaseKeyword.__New.bind(this), while using base as a key (this.base.__New( "b" )) calls __New like any other function (in particular: this hidden parameter isn't passed to the function):

Code: Select all

_o := new BaseKeyword2 ; shows the message box 3 times, not twice

class BaseKeyword {
y :=11
    __New( s ) {
        msgbox % s . this.x . A_Space . this.y
    }   
    
}
class BaseKeyword2 extends BaseKeyword {
x :=11
    __New() {

        base.__New( "a" ) ; this calls BaseKeyword.__New.bind(this) i;e. THIS FUNCTION
        this.base.__New( "b" ) ; this calls this.__New WITHOUT ANY BOUND PARAMETERS: this.x and this.y are not displayed
        ; this.base.__New.bind(this, "b" ).call() ; if you put only this line you will get an infinite recursion.... (ahk will crash)
    }    
}
Last edited by A_AhkUser on 23 Nov 2017, 12:51, edited 1 time in total.
Helgef
Posts: 4110
Joined: 17 Jul 2016, 01:02
Contact:

Re: base.method() and this.base.method() Confusion

23 Nov 2017, 12:34

A_Hello :wave: I try to give a step-by-step.
First, you do

Code: Select all

_o := new BaseKeyword2
which calls

Code: Select all

__New() {
	base.__New( "a" )
this goes

Code: Select all

 __New( s ) {
	msgbox % s ; a
then back to this line

Code: Select all

this.base.__New( "b" )
where this.base refers to the class BaseKeyword2, so you call BaseKeyword2.__new("b"), passing BaseKeyword2 as the hidden this parameter, which goes to

Code: Select all

__New() {
	base.__New( "a" ) ; -> msgbox a again
passing an excessive paramter ("b") doesn't cause an error. Again, you return and come to

Code: Select all

this.base.__New( "b" )
where this.base is BaseKeyword2.base, which now refers to BaseKeyword, so you get to

Code: Select all

 __New( s ) {
	msgbox % s ; b
All calls are done, everything returns and assings _o.

Cheers
A_AhkUser
Posts: 1076
Joined: 06 Mar 2017, 16:18
GitHub: AAhkUser
Location: France

Re: base.method() and this.base.method() Confusion

23 Nov 2017, 12:47

where this.base is BaseKeyword2.base, which now refers to BaseKeyword
My head's spinning :crazy:

Thanks for you input Helgef ;)
A_User
Posts: 36
Joined: 21 Aug 2017, 01:15

Re: base.method() and this.base.method() Confusion

23 Nov 2017, 17:23

Thanks for breaking it down, Helgef.
Helgef wrote:where this.base refers to the class BaseKeyword2
This is hard to understand...; `this.base` does not refer to the base object but the derived object for the first time.

This seems to be the AutoHotkey way, however. I don't think I fully understand this behavior and I decided to stay away from `this.base`.

I leave the below note for anybody who gets similar confusion.

Code: Select all

global iCallCount := 0

o := new BaseKeyword2 
msgbox % "Result`n"
       . "p: " o.iCallCount "`n"  ; shows 1
       . "g: " iCallCount         ; shows 2

class BaseKeyword {
    
    __New() {
    }   
    
}
class BaseKeyword2 extends BaseKeyword {

    iCallCount := 0

    __New() {
        
        this.base.__New()
        ; base.__New()      ; does not cause the issue
        iCallCount++        ; gloval variable
        this.iCallCount++   ; class property
        
        this.check( iCallCount, this.iCallCount )
        
    }    

    check( iGlobalCount, iPropertyCount ) {
        msgbox % A_ThisFunc "`n"
            . "p: " iPropertyCount "`n"
            . "g: " iGlobalCount 
    }
    
}
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: base.method() and this.base.method() Confusion

04 Jul 2018, 17:10

Code: Select all

q::
vOutput := ""
Loop, 8
{
	vNum := A_Index-1
	vName := ""
	vName .= (vNum & 0x4) ? "A_" : ""
	vName .= (vNum & 0x2) ? "Ahk" : ""
	vName .= (vNum & 0x1) ? "User" : ""
	if (vName ~= "^(A_(Ahk)?)?User$")
		vOutput .= "Hello " vName "!`r`n"
}
MsgBox, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
nnnik
Posts: 4387
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: base.method() and this.base.method() Confusion

05 Jul 2018, 02:15

A_User wrote:Thanks for breaking it down, Helgef.
Helgef wrote:where this.base refers to the class BaseKeyword2
This is hard to understand...; `this.base` does not refer to the base object but the derived object for the first time.

This seems to be the AutoHotkey way, however. I don't think I fully understand this behavior and I decided to stay away from `this.base`.

I leave the below note for anybody who gets similar confusion.

Code: Select all

global iCallCount := 0

o := new BaseKeyword2 
msgbox % "Result`n"
       . "p: " o.iCallCount "`n"  ; shows 1
       . "g: " iCallCount         ; shows 2

class BaseKeyword {
    
    __New() {
    }   
    
}
class BaseKeyword2 extends BaseKeyword {

    iCallCount := 0

    __New() {
        
        this.base.__New()
        ; base.__New()      ; does not cause the issue
        iCallCount++        ; gloval variable
        this.iCallCount++   ; class property
        
        this.check( iCallCount, this.iCallCount )
        
    }    

    check( iGlobalCount, iPropertyCount ) {
        msgbox % A_ThisFunc "`n"
            . "p: " iPropertyCount "`n"
            . "g: " iGlobalCount 
    }
    
}
It's not confusing at all - you just need to think about this more calmly.
An objects base is it's class - a classes base is the class it extends.
this.base refers to the objects base therefore in your case BaseKeyword2.
this.base.base refers to the objects bases base in your case BaseKeyword.
The base keyword in a class (a horrible name choice if you ask me) will refer to the current classes base regardless of what this contains.

If you wanted to replace the base keyword in a class you would have to use this.base.base -since both refer to the classes base.
Recommends AHK Studio

Return to “Ask For Help”

Who is online

Users browsing this forum: flyingDman, JnLlnd and 64 guests