basic class example for AHKv2 - methods and properties

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

basic class example for AHKv2 - methods and properties

16 Mar 2020, 15:49

This code works the way I intend, so it seems I'm on the right track for basic methods and properties.

Code: Select all

class MyClassName {
	__New() {
		this.property := "new-init" ; "this" works in __New()
	}
	property {
		set => MyClassName.property := value ; if I use "this" here then it hangs and crashes and hangs
		get => MyClassName.property          ; if I use "this" here then it hangs and crashes and hangs
	}
	method(x,y) {
		return x+y
	}
}

myclass := MyClassName.new()
myclass.property := "change" ; comment this out to get init value

msgbox "test: " myclass.property
msgbox myclass.method(3,2)
The thing that confuses me is that I'm used to seeing this.property instead of MyClassName.property in most examples. Is the need to use MyClassName intentional? Or did I miss something? If I try this.property to set or get a value, it hangs and crashes in several instances.

Using AutoHotkey Unicode 64-bit 2.0-a108-a2fa0498

EDIT: oy sorry ... had to edit code
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: basic class example for AHKv2 - methods and properties

16 Mar 2020, 17:18

What you want is probably this:

Code: Select all

class MyClassName {
	__New() {
		this.property := "new-init"
	}
	__property[name] {
		set => this.%name% := value
		get => this.%name%
	}
	method(x,y) {
		return x+y
	}
}

myclass := MyClassName.new()
myclass.property := "change" ; comment this out to get init value

msgbox "test: " myclass.property
msgbox myclass.method(3,2)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 00:24

@TheArkive, the point you are missing is that in

Code: Select all

property {
	set => this.property := value 
	get => this.property          
}
you will invoke the property inside of it, i.e, you cause infinite recursion, just like in

Code: Select all

f(){
	f	
}
When you use MyClassName.property you avoid the recursion, but all instances of MyClassName will write to the same property, so only one instance can be used at one given time to store a value there. What you are more likely to want is to use this.myOtherProperty, ie.,

Code: Select all

property {
	set => this.myOtherProperty := value 
	get => this.myOtherProperty          
}
@HotKeyIt, I do not follow.

Cheers.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 02:40

Thanks guys for setting me straight. Makes sense.

@HotKeyIt
I never knew about __property[name] in a class definition. I can't seem to find that in the help docs. Is that related to __Item[name]??

@Helgef
Thanks for the explanation about infinite recursion. I didn't realize that is what was happening. Other than what @HotKeyIt mentioned, how would I use your suggestion to populate a specific property if I have to rename that property to something else?

My though was to populate:

Code: Select all

myClass.property := "something"
and recall:

Code: Select all

recallVar := myClass.property
Just not sure how that works when renaming the property to something else.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 03:06

I am not sure what you are asking, the name property (and __property) is just an example, it could be anything, eg,

Code: Select all

banana {
	set => this.myBanana := value 
	get => this.myBanana
}
For any property definition, you can define parameters in brackets following the property name, eg,

Code: Select all

banana[length := 0] {
	set => length < 10 ? error() : this.myBanana := value
	get => this.myBanana
}
__item is a special property only in that it has a short hand to invoke it, which is the brackets [] notation, that is, o[p*] is equivalent to o.__item[p*].

Cheers.
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 03:33

Helgef wrote:
17 Mar 2020, 00:24
@HotKeyIt, I do not follow.
__Property[Name] seems to be equivalent to __Item[Name] but for properties, though it is not mentioned in the documentation.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 03:41

Helgef wrote:
17 Mar 2020, 03:06
I am not sure what you are asking, the name property (and __property) is just an example, it could be anything, eg,

Code: Select all

banana {
	set => this.myBanana := value 
	get => this.myBanana
}
Sorry for being unclear. I am a bit of a novice at certain levels of OOP. I can use objects just fine in most cases, though creating classes is still something I'm getting used to.

I understood that .property is meant to be anything. Though __property seemed like one of those "special" elements like __item. Is it not?

To use your example. If I specifically want to populate banana and not myBanana, using your example is that possible?

In AHK 1, I didn't seem to need to actually define properties with Set/Get. If I used this.something := "a thing" anywhere in the class definition, then .something was populated. Maybe that wasn't supposed to work, but it did.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 03:43

@HotKeyIt
Thanks for that. So one definition like that can suffice for all properties? Even unnamed ones? And I presume a multi-line Set/Get { ... } can be used to perform more complex operations to store/retrieve values?
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 03:57

You don't need the property definition in the class to be able to set and get property:

Code: Select all

class MyClassName {
}
myclass := MyClassName.new()
myclass.property := "change"
msgbox "test: " myclass.property
If you want to do more complex operations or control the properties __property seems to be perfect for that.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 04:23

I'm in the process of converting one of my classes to AHK v2, and was having some issues. Looks like I need to initialize each property I want to use with default or blank values in __New() which makes sense in AHK v2.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 04:47

HotKeyIt wrote:
17 Mar 2020, 03:33
Helgef wrote:
17 Mar 2020, 00:24
@HotKeyIt, I do not follow.
__Property[Name] seems to be equivalent to __Item[Name] but for properties, though it is not mentioned in the documentation.
It seems not, and even if it was, your example would cause infinite recursion like the op's.
TheArkive wrote: Is it not?
It is not!

If you want some special behaviour when invoking a property, you define it with the prop[] {get=> set=>} syntax, or .defineProp(), if you just want to store a value, just assign it, myObj.myprop:=myval.

Cheers.
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 05:14

Helgef wrote:
17 Mar 2020, 04:47
HotKeyIt wrote:
17 Mar 2020, 03:33
Helgef wrote:
17 Mar 2020, 00:24
@HotKeyIt, I do not follow.
__Property[Name] seems to be equivalent to __Item[Name] but for properties, though it is not mentioned in the documentation.
It seems not, and even if it was, your example would cause infinite recursion like the op's.
Try the example, it definitely works:

Code: Select all

class MyClassName {
	__property[name] {
		set => this.%name% := value
		get => this.%name%
	}
}

myclass := MyClassName.new()
myclass.property := "change"
msgbox "test: " myclass.property
for k,v in myclass.OwnProps()
    MsgBox k " = " v
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 05:26

HotKeyIt wrote:
17 Mar 2020, 05:14
Try the example, it definitely works:

Code: Select all

class MyClassName {
	__property[name] {
		set => this.%name% := value
		get => this.%name%
	}
}

myclass := MyClassName.new()
myclass.property := "change"
msgbox "test: " myclass.property
for k,v in myclass.OwnProps()
    MsgBox k " = " v
That worked for me too. No infinite recursion.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 06:27

Try the example, it definitely works
that should hint to you that it doesn't do what you think. __property has nothing to do with the behaviour of that script. If it did what you claimed, it wouldn't work.

Cheers.
User avatar
kczx3
Posts: 1644
Joined: 06 Oct 2015, 21:39

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 08:50

This is why I hate property getters/setters in AHK. The fact that what you store actually must store into something completely different is super annoying to me. I'd prefer that this.whatever in a setter would just bypass the setter and avoid the infinite recursion altogether. I tend to just stick with "Hey, just make sure you set this property to X" or creating setter/getter methods that handle it.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 08:56

its the same in c#. a property has to have a backing field and avoid self-referencing itself(ie the property. reference the backing field instead). except in c# u can make the field private, so it has some uses, whereas in ahk u cant...ish
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 17:28

Helgef wrote:
17 Mar 2020, 06:27
Try the example, it definitely works
that should hint to you that it doesn't do what you think. __property has nothing to do with the behaviour of that script. If it did what you claimed, it wouldn't work.

Cheers.
Not sure what you mean, did you try the script? It does exactly what I think as you can see in for loop, property is set as expected.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: basic class example for AHKv2 - methods and properties

17 Mar 2020, 23:38

Not sure what you mean
I mean that __property has nothing to do with the behaviour of that script. If it did what you claimed, it wouldn't work at all because it would cause infinite recursion. I.e, the only thing true here,
HotKeyIt wrote: __Property[Name] seems to be equivalent to __Item[Name] but for properties, though it is not mentioned in the documentation.
is the last statement, and for good reasons: __property has no special meaning. You can rename __property to __banana or just remove it.
It does exactly what I think as you can see in for loop, property is set as expected.
I expect the property to be set because you set it: myclass.property := "change". But again, it has nothing to do with __property. If you want to set it using the __property property, you have to invoke it, i.e., myclass.__property['property'] := 'change', that is perfectly fine, and you can do the same if you rename __property to __banana.

Cheers.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: basic class example for AHKv2 - methods and properties

18 Mar 2020, 02:21

I think __property[name] isn't doing anything as @Helgef says.

Code: Select all

class MyClassName {
	__New() {
		this.property := "new-init"
	}
	__property[name] {
		set
		{
			msgbox "setting the prop: " name
			this.%name% := value
		}
		get
		{
			msgbox "getting the prop: " name
			this.%name%
		}
	}
	method(x,y) {
		return x+y
	}
}

myclass := MyClassName.new()
myclass.property := "change" ; comment this out to get init value

msgbox "test: " myclass.property
msgbox myclass.method(3,2)
If it was doing something wouldn't the added msgbox entries display stuff?

My issue from the OP was that I was trying to reference a prop value that I didn't set. AHKv2 doesn't let that happen like in AHKv1. So my solution is simple. Just initiate all values on myClass.New() within the __New() member. I don't even need set/get to do that.

Sorry for fueling this one (unintentionally) @Helgef. I bet we're all tired of misinformation these days...

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 55 guests