Classes in AHK, a Dissection (Advanced)

Helpful script writing tricks and HowTo's
User avatar
ahkDustVorteX
Posts: 47
Joined: 14 May 2014, 12:08

Re: Classes in AHK, a dissection

02 Feb 2015, 18:07

Hey Guys,

Firstly, congrats to GeekDude. Your explanation made more clear what classes are. I do not have a solid base in programming and this explanation was pretty helpful.

But it seems that this created a healthy discussion in this thread where some concepts are arguable, at least in AHK. Which is pretty enjoyable to read.

By the way:

Then it calls the (reserved by AutoHotkey, don't ever define this unless you want to die a painful death) __Init() meta-function.


This was hilarious! :D

Thanks for all this information
Editor: Notepad++
"Those who wait and persist, always achieve."
GeekDude
Posts: 838
Joined: 02 Oct 2013, 22:13

Re: Classes in AHK, a Dissection (Advanced)

03 Feb 2015, 19:01

It has come to my attention that the term "property" refers specifically to dynamic values, not normal values like I've been using it to refer to. Also, I have no idea how actual properties are implemented in AHK (that is, I'm familiar with the sugar syntax but not the behind-the-scenes), so if someone could shed a light...
guest3456
Posts: 2403
Joined: 09 Oct 2013, 10:31

Re: Classes in AHK, a Dissection (Advanced)

03 Feb 2015, 21:23

GeekDude wrote:It has come to my attention that the term "property" refers specifically to dynamic values, not normal values like I've been using it to refer to. Also, I have no idea how actual properties are implemented in AHK (that is, I'm familiar with the sugar syntax but not the behind-the-scenes), so if someone could shed a light...


Similarly how Lexikos said "class" can be a very broad term, so could "property". So again it comes down to whether you want to be specific with how AHK implements these terms or how generic usages use these terms. In AHK, a class "property" allows you to define getter/setter routines when accessing a specific key in an object in case you need to do some other processing. Afaik, instead of having to use the __Get or __Set meta functions and then parsing out a particular key name, the property syntax is a more convenient way of keep that functionality grouped together

GeekDude
Posts: 838
Joined: 02 Oct 2013, 22:13

Re: Classes in AHK, a Dissection (Advanced)

03 Feb 2015, 21:27

guest3456 wrote:In AHK, a class "property" allows you to define getter/setter routines when accessing a specific key in an object in case you need to do some other processing. Afaik, instead of having to use the __Get or __Set meta functions and then parsing out a particular key name, the property syntax is a more convenient way of keep that functionality grouped together


Which is the same definition the Wikipedia entry for the word "property" gives, more or less.

Wikipedia wrote:A property, in some object-oriented programming languages, is a special sort of class member, intermediate between a field (or data member) and a method. Properties are read and written like fields, but property reads and writes are (usually) translated to get and set method calls. The field-like syntax is said to be easier to read and write than lots of method calls, yet the interposition of method calls allows for data validation, active updating (as of GUI visuals), or read-only 'fields'. That is, properties are intermediate between member code (methods) and member data (instance variables) of the class, and properties provide a higher level of encapsulation than public fields.
GeekDude
Posts: 838
Joined: 02 Oct 2013, 22:13

Re: Classes in AHK, a Dissection (Advanced)

13 Feb 2015, 08:00

I've replaced every instance of "Property" with "Attrubute", and will probably be needing to write a bit on properties once I have some idea how they're implemented
User avatar
jethrow
Posts: 183
Joined: 30 Sep 2013, 19:52
Location: Iowa

Re: Classes in AHK, a Dissection (Advanced)

15 Feb 2015, 01:26

Concerning class semantics, here is a related conversation: Keyword Prototype instead of Class

I generally agree with Lexikos' semantics viewpoint - I just think it may lead to confusion with folks who are coming from or going to a Class-based programming language.
-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Re: Classes in AHK, a Dissection (Advanced)

08 Oct 2015, 15:34

I find the 'Understanding class instances (and the new keyword).' part of this tutorial a bit unclear/weird. The whole idea of instances is that you may use same class (but maybe different methods in it) by different objects, isn't it? Then the example should demonstrate the use of at least two instances, that use the same class (and the same and/or different methods in it) to prove the use of such approach in coding.

Same is for the 'Understanding inheritance' part: okay, there is some inheritance between base objects and instances and the user can break the inheritance, where's the example showing what's the actual use/benefit from that?

As for the 'How meta-functions work' part - it's so confusing that I didn't understand a thing.

Give a thought to use colors to distinguish types of discussed objects (base/methodname/instance/etc).

No offense, I just thought that negative feedback is still a feedback.
GeekDude
Posts: 838
Joined: 02 Oct 2013, 22:13

Re: Classes in AHK, a Dissection (Advanced)

08 Oct 2015, 21:39

I wrote this as a way to clarify how things work 'under the hood' after you're already familiar with how/why/when to use classes. I suppose I could write another tutorial (or modify this one) to be aimed at people wanting to learn about those things, but my life has gotten quite a bit busier of late. I'll throw it onto my mental roster and see if I ever get around to it (I have a depressingly large backlog, so it may take a while).
User avatar
Soft
Posts: 174
Joined: 07 Jan 2015, 13:18
GitHub: visionary1
Location: Seoul
Contact:

Re: Classes in AHK, a Dissection (Advanced)

15 Oct 2015, 09:30

I have a question about variables and inheritance
When static variables got changed, how can I interact with that variables from inherited class?
I'm not good at English, hence I guess giving you an example would be better

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Var is set to 0 when script starts.
if you click 'Method_A', this.var is set to 1
if you click 'Method_B', this.var is set to 2

however, when I click 'Method_B' then 'Method_A'. MsgBox says Var is 0 although Method_B changed the value to 2
I think 'this.var' is not sharing between two classes

can you point out what's wrong?
Thanks.
AutoHotkey & AutoHotkey_H v1.1.22.07
lexikos
Posts: 6130
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Classes in AHK, a Dissection (Advanced)

15 Oct 2015, 16:43

The value is shared, not the "variable". If you assign this.var := something, this will have its own variable named "var".

Assign to A.Var if you want to affect that variable.
User avatar
Soft
Posts: 174
Joined: 07 Jan 2015, 13:18
GitHub: visionary1
Location: Seoul
Contact:

Re: Classes in AHK, a Dissection (Advanced)

16 Oct 2015, 14:23

lexikos wrote:The value is shared, not the "variable"....


Thank you lexikos,
but isn't class B inherited every variable from class A? I'm confused :?
AutoHotkey & AutoHotkey_H v1.1.22.07
lexikos
Posts: 6130
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Classes in AHK, a Dissection (Advanced)

16 Oct 2015, 17:41

No, only the value (read-only).
guest3456
Posts: 2403
Joined: 09 Oct 2013, 10:31

Re: Classes in AHK, a Dissection (Advanced)

16 Oct 2015, 19:10

Soft wrote:but isn't class B inherited every variable from class A? I'm confused :?


B inherited the values of A as soon as the object was extended/prototyped/whatever.
since you're extending a class, this happened upon script startup.
A.var was 0, so B made a copy of 0 in B.var

you pressed MethodB and changed this.var which is B's copy (B.var) to 2.

when you press MethodA, it changed this.var which is A's copy ( A.var ) which was still 0, and then changes that to 1


lexikos wrote:Assign to A.Var if you want to affect that variable.

base.Var would work the same too right?

lexikos
Posts: 6130
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Classes in AHK, a Dissection (Advanced)

17 Oct 2015, 04:37

@guest3456: Unless I'm misunderstanding you, you're wrong on all counts.

It's explained under "Prototypes":
An object is a prototype or base if another object derives from it:

Code: [Select all] [Download] GeSHi © Codebox Plus

other := {}
other.base := thing
other.test()
In this case, other inherits foo and test from thing. This inheritance is dynamic, so if thing.foo is modified, the change will be reflected by other.foo. If the script assigns to other.foo, the value is stored in other and any further changes to thing.foo will have no effect on other.foo. When other.test() is called, its this parameter contains a reference to other instead of thing.
Source: Objects - Custom Objects - Prototypes

There is a misleading line:
To access a class variable, always specify the class or derived object; for example, ClassName.ClassVar.
Source: Objects - Classes
You can read the static/class variable via a derived object, but you cannot write to it, because the assignment would create a new key-value pair in the derived object (as I mentioned earlier).

The process of inheritance is described in detail under Meta-Functions. Specifically, inheritance of a value from class object to derived object is covered by this bullet point:
If a key was found,
Get: Return the value.


guest3456 wrote:base.Var would work the same too right?
There is a discussion somewhere on one of the forums about why base.Var := 1 does nothing.
guest3456
Posts: 2403
Joined: 09 Oct 2013, 10:31

Re: Classes in AHK, a Dissection (Advanced)

17 Oct 2015, 08:36

you understand me correctly.

i was wrong on all counts! :(

-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Re: Classes in AHK, a Dissection (Advanced)

25 Oct 2015, 19:37

I have a question about classes.
Say, I have a class with method __New(), that populates 'this' object (I guess it's called 'base') with some data.
So, if I newobj := new myClass(), the newobj will get populated with some data.
After that - can I use the same newobj := new myClass() to get populated again so that the object would contain old data + new data (new data should overwrite old data if there is a conflict)?
An experiment showed that it won't work: __new() each time creates a fresh new empty object first (a new instance) before populating it and thus the old data get lost.
Can I 'ByRefy' this somehow? Or should I just forget about __new() and create a normal method instead that would require an object to be referenced as an argument's input value?
lexikos
Posts: 6130
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Classes in AHK, a Dissection (Advanced)

25 Oct 2015, 20:31

-_+ wrote: Or should I just forget about __new() and create a normal method instead
__New() is just a method. You can call newobj.__New() or name the method something else.

If the method is defined in the class which newobj is an instance of, there is no need to pass newobj explicitly. Just call newobj.aNormalMethod() and refer to this within the method.

So, if I newobj := new myClass(), the newobj will get populated with some data.
No, a new object will be created and populated with data, and then it will be assigned to newobj, replacing whatever value it previously had. Within __New, the script's only reference to the object so far is in this (unless you call __New manually).
-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Re: Classes in AHK, a Dissection (Advanced)

26 Oct 2015, 08:12

lexikos, thanks for answering to some of my questions, but the main one was unanswered:
Is there a way to pass an existing object (already populated with some data) to a class's methods, so that:
- they would work with that object instead of creating a new one and overwriting the new one's data into the existing one;
- the existing object would be referred not directly by it's name, but rather by something like this or anyhow else?

I see you suggested to just call newobj.aNormalMethod(), but it can't be called until I bind newobj to the specified class first. And I know only one way to do that - to instantiate it via newobj := new MyClass(), which would flush the existing data of the object I bind to the class.
lexikos
Posts: 6130
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Classes in AHK, a Dissection (Advanced)

26 Oct 2015, 16:25

You asked:
can I use the same newobj := new myClass() [...]?
In that case, newobj is already an instance of myClass and you can just call one of its normal methods, as I said.

If you actually meant to use a different class the second time, that's a different question which you didn't ask. If you want to override this to be an instance of a different class, use the Call method, as in SomeClass.SomeMethod.Call(newobj) (or rethink your design).

- the existing object would be referred not directly by it's name, but rather by something like this or anyhow else?
Objects don't have names. Variables have names, and you often (but not always) assign objects to variables. If you pass the object as a parameter, you can call the parameter whatever you want, be it "something like this" or more "name-like". If you use a function instead of a method, you can even call it "this".

Return to “Tutorials”

Who is online

Users browsing this forum: No registered users and 6 guests