Class Static Variable assess

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
RFM
Posts: 28
Joined: 21 May 2016, 12:50

Class Static Variable assess

19 Feb 2017, 16:52

AHK Version 1.1.24.05, Windows 7 Ultimate 64 bit.

Look at the Counter property for a description of the bug.

Code: Select all

Class Class02
{
	static CurVer := 1.1, Instances := 0, MaxInstancesAllowed := 3, Cnt := 0
	Instance := 0
	EM := ""
	
	__New()
	{
		this.Instance := ++Class02.Instances
		if (this.Instance > Class02.MaxInstancesAllowed)
		{
			this.EM := "You attempted to create instance " . this.Instance . " when only " . Class02.MaxInstancesAllowed . " instances are allowed!`n`nInstance was not created!"
			return null
		}
		MsgBox % "Instance " . this.Instance . " was created!"
	}
	
	__Delete()
	{
		MsgBox % this.EM = "" ? "Instance " . this.Instance . " is being deleted!" : this.EM
		Class02.Instances -= 1
	}
	
	Version
	{
		get
		{
			return Class02.CurVer
		}
	}
	
	Counter
	{
		get
		{
		; **************************************************************************** BUG
		;                                                                   ; Line ; *
			Class02.Cnt += 1                                                  ;  A   ; *
			this.Cnt += 1                                                     ;  B   ; *
			;return Class02.Cnt ; Returns 1, 2, 3 correctly.                   ;  C   ; *
			return this.Cnt ; Returns 2, 3, 4 This is incorrect!              ;  D   ; *
			; How did this.Cnt start off being 2?  My guess is that it inheits the   ; *
			; value of Class02.Cnt at the time it is first used.  That is why        ; *
			; changing the order of lines A and B give different results.            ; *
			; This could cause hard to track down bugs.                              ; *
			; If you reverse the order of lines A and B, both return correct values. ; *
			; Uncommet line C or D and comment the other.                            ; *
			;                                                                        ; *
			; While on the subject, having to use the class name within its own      ; *
			; property or method is not good, there should be no external names      ; *
			; used within an instance to access any of the class' variables.  I've   ; *
			; never seen this before.  My thought on the matter is that this.Cnt     ; *
			; would always reference the static variable, just like in other         ; *
			; languages, and where a static variable exists, no instance variable of ; *
			; the same name should be created.  They are all part of the same class, ; *
			; static or instance.  If the developer needs a copy of the static       ; *
			; variable at the time the class is instantiated, he can simply make a   ; *
			; copy in the ___New() method which is called when instantiated.  If     ; *
			; what I think happened is true, that __New() is a later addition and    ; *
			; there was no way to get a copy of the static variables at the time it  ; *
			; was instantiated, I understand why things work the way they do.  But,  ; *
			; I hope this isn't carried into V2, but rather corrected to be like     ; *
			; most, if not all, other languages implementing classes.                ; *
		; ****************************************************************************
		}
	}
	
	MyInstance
	{
		get
		{
			return this.Instance . " of " . this.MaxInstancesAllowed
		}
	}
	
	GetInstance()
	{
		MsgBox % "This is instance " . this.Instance . " of " . Class02.Instances . " instances."
	}
}

c01 := New Class02
c02 := New Class02
c03 := New Class02
c04 := New Class02

MsgBox % "Version: " . c01.Version . ", Instance: " . c01.MyInstance . ", Counter: " . c01.Counter
MsgBox % "Version: " . c02.Version . ", Instance: " . c02.MyInstance . ", Counter: " . c02.Counter
MsgBox % "Version: " . c03.Version . ", Instance: " . c03.MyInstance . ", Counter: " . c03.Counter
MsgBox % "Version: " . c04.Version . ", Instance: " . c04.MyInstance . ", Counter: " . c04.Counter

MsgBox All Instances have been created.
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: Class Static Variable assess

19 Feb 2017, 17:28

This is not a bug but documented behavior, see Static/Class Variables
To assign to a class variable, always specify the class object; for example, ClassName.ClassVar := Value. If an object x is derived from ClassName and x itself does not contain the key "ClassVar", x.ClassVar may also be used to dynamically retrieve the value of ClassName.ClassVar. However, x.ClassVar := y would store the value in x, not in ClassName.
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Class Static Variable assess

19 Feb 2017, 18:30

Again, your lack of understanding of prototype-based OOP in AHK leads you astray. But you already know it all, so you will continue to be confused while writing multiple paragraph posts condescending AHK's design and everyone else who responds to you. IMO, a better discussion would be on whether or not the 'class' keyword should even be used in AHK in order to prevent misunderstandings such as this. But Lexikos was careful to define his usage of the word 'class' in the docs, choosing a broad definition. But its still easy for new users to be confused

You should be posting in Ask For Help

RFM
Posts: 28
Joined: 21 May 2016, 12:50

Re: Class Static Variable assess

19 Feb 2017, 22:59

HotKeyIt wrote:However, x.ClassVar := y would store the value in x, not in ClassName.
I already read that, it does not address my main point. However, further research pulled up something that did:
GeekDude wrote:
Understanding inheritance


When AutoHotkey goes to find a attribute in your object, it first does the meta-function object.base.__Get check, then it moves on to "Does attribute exist in the object?". If it does, it uses it. If not it checks "Does it exist in the object's base?". If it does, it uses it. If not, it checks the base's base, and then the base's base's base, and so on until there are no more base objects.

When AutoHotkey goes to set a attribute in your object, it just creates the attribute in the original object. Consider closely what the following code will do:

Code: Select all

x := new y
MsgBox, % x.Attribute
y.Attribute := 3
MsgBox, % x.Attribute
x.Attribute -= 1
y.Attribute := 7
MsgBox, % x.Attribute

class Y
{
	static Attribute := 5
}
On line one, it creates an instance of y (think x := {base: y}). On line two, it tries to get x.Attribute. Seeing that x doesn't have a Attribute, and that x.base does, it returns x.base.Attribute (5) instead. On line three, it changes y.Attribute to 3. x still doesn't have a Attribute, and y is still the base of x, so on line 4 it sees when it sees that x doesn't have a Attribute it returns x.base.Attribute (aka y.Attribute, with the value of 3) instead. On line 5 it pulls the value of x.Attribute, but sees that it doesn't have a Attribute and instead uses x.base.Attribute, then it subtracts 1 from that and gives x a Attribute of 2. Since x now has a Attribute, any further changes to y.Attribute are not inherited, and the value 2 will be shown on line 7.
In my class in the first post, when the two lines of code are run in the order below for the first time:
Class02.Cnt += 1
this.Cnt += 1
"this.Cnt" will have a "2" in it.

However, in my class in the first post, when the same two lines of code ran in the order below for the first time:
this.Cnt += 1
Class02.Cnt += 1
"this.Cnt" will have a "1" in it.

When I go from one language to the next, I've always been able to count on things in a class working the same, and they do, though the implementation my be different. AHK does some quirky things when it comes to classes, things you don't find in other languages, and things that are not in compliance with the behavior generally expected of classes. So, when I implement a class in AHK the way I would in any other language, I initially expect it to function as it would in any other language.

I initially thought, like in all other languages, the "this.Cnt" would only access the class' static Cnt. When it didn't, going to the help documentation I discovered why. But, nowhere in the help documentation did I find the answer for the two sets of two lines of code above producing different results. After I posted my prior message my search brought up "Understanding inheritance" by the GeekDude. That should be in the help documentation.

If there were multiple threads that changed the value of Class02.Cnt, you could not rely on the result of the first run of this code:
Class02.Cnt += 1
this.Cnt += 1
as "this.Cnt" could have anything in it.
One might think that the solution in AHK is to make Cnt an instance variable:
static CurVer := 1.1, Instances := 0, MaxInstancesAllowed := 3, Cnt := 0
Cnt := 0
But, you cannot do that. When you run the script, you get "Error: Duplicate declaration."
There are two scopes, class static and instance, and they are both recognized by AHK, but, for any given name, you can only define it in one scope or the other, not both. You have to create the instance variable by assigning it a value in a method or property. That is a BUG!

The next thought is to put this.Cnt := 0 in the __New() method. That worked! So, if you want an instance scope variable with the same name as the static scoped, and you want it initialized, you have to initialize it in the a method or property, the __New() method being the best place.

But, nonetheless, if AHK is going to recognize two scopes so that they both can have a variable with the same name, they should not tread on or derive from each other at all. Doing so makes the result highly unreliable, as seen by this.Cnt += 1 above, and a source for hard to find bugs. Two lines of code using two different variables, even with the same name, but different scopes, should NEVER EVER have different results depending on the order in which they are run. That is a BUG no matter how you slice. And just because it is documented, that does not make it not a BUG. I know of no other language that would not consider that a huge bug.

So, the immediate solution is, don't have instance variables with the same name as static variables in the same class. The best solution is, like in all other languages, this.var is the same as className.var. This will eliminate the need to use className.var in that class' own methods and properties.


Having to use the defining class' name to access the class' static variables within that class' own properties and methods is highly irregular. If I ever change the class' name, I'll have to change all occurrences of its name used in that class. I did some searching to find out if I can somehow retrieve the class' name and put it in an instance variable, but, I couldn't find out how or if it could be done.

So, I tried the following:
ClassName := "Class02"
And then in the __New() method I did this:
this.Instance := ++%this.ClassName%.Instances
but that give me this error: "Error: Ambiguous or invalid use of ".""
So, I did this in the __New() method:
ClassName := this.ClassName
this.Instance := ++%ClassName%.Instances
And that worked. But, that means, in every method and property I'll be accessing a static variable, I have to do the following:
ClassName := this.ClassName
<some code with:> %ClassName%.<Var>


I see that in V2, AHK is attempting to be more standard, meaning, closer to other languages in functionality, I hope classes become like other languages as well, especially in regards to the things above.
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Class Static Variable assess

20 Feb 2017, 00:18

RFM wrote: In my class in the first post, when the two lines of code are run in the order below for the first time:
Class02.Cnt += 1
this.Cnt += 1
"this.Cnt" will have a "2" in it.

However, in my class in the first post, when the same two lines of code ran in the order below for the first time:
this.Cnt += 1
Class02.Cnt += 1
"this.Cnt" will have a "1" in it.
HotKeyIt's quote addresses the same thing that GeekDude's does, and BOTH address the order or your two lines above.

lexikos
Posts: 9589
Joined: 30 Sep 2013, 04:07
Contact:

Re: Class Static Variable assess

20 Feb 2017, 04:07

Inconsistency with your own image of how the language should be does not constitute a bug.
RFM wrote:How did this.Cnt start off being 2? My guess is that it inheits the value of Class02.Cnt at the time it is first used.
There's no need for guessing. The dynamic nature of inheritance in AutoHotkey is explained and demonstrated repeatedly in the object documentation. The "Meta-Functions" section goes into detail about the exact mechanics.
Two lines of code using two different variables, even with the same name, but different scopes, should NEVER EVER have different results depending on the order in which they are run.
You are not dealing with two different variables until this.Cnt += 1 creates the instance variable. As you know, it is shorthand for this.Cnt := this.Cnt + 1. On the right is initially a reference to the class variable, because there is no such instance variable. (Or so it could be seen. In reality, it is not a variable reference but a query which is applied against the object and its bases.)
I did some searching to find out if I can somehow retrieve the class' name and put it in an instance variable, but, I couldn't find out how or if it could be done.
Why would you ever do that?

What class are you referring to? You already know which class you defined the variable in, so you can write it's name directly. If you have multiple classes derived from that class and you wish to refer to the class which this directly derives from, that would be this.base.

If you've somehow concocted a real need for the class name, perhaps A_ThisFunc or this.__Class (inherited from the class) has what you want.
That is a BUG no matter how you slice.
You can argue all you like, but if no one is willing to take action based on your opinion, you will only be wasting time.
AHK does some quirky things when it comes to classes, things you don't find in other languages
Yes, classes are consistent with the other parts of the language in that respect. ;)
RFM
Posts: 28
Joined: 21 May 2016, 12:50

Re: Class Static Variable assess

20 Feb 2017, 10:44

lexikos wrote:Inconsistency with your own image of how the language should be does not constitute a bug.
I made it clear throughout the post that is it NOT my "own image of how the language should be", it IS the actual "image" common among all the high caliber languages used to develop sophisticated robust software. I know of no other language that strays from what is well documented and commonly accepted standard of class functionality. Can you show me another language that takes code equivalent to this:
static Cnt := 3 ; Scope: static class variable.
this.Cnt += 1 ; Scope: instance variable of class.
this.Cnt += 1 ; Scope: instance variable of class.
that results in this.Cnt being = 5 (the instance variable) and className.Cnt = 3 (the static variable)
In all languages I've worked with classes in, the results are this.Cnt = 5 and className.Cnt = 5 because you cannot have two variables declared as such:
static Cnt := 3
Cnt := 0
and be in two different scopes. In fact, AHK itself won't allow such a declaration and gives the "Error: Duplicate declaration." message, yet it recognizes both scopes within methods and properties, Cnt as a static class variable and Cnt as an instance variable. And, within methods and properties, a third scope is recognized, Cnt without the "this." or "className." before it is a local scope. And, there is the super global scope, as long as the super global variable does not have the same name as a variable within the class, but there are exceptions, still being tested.

My comparison is NOT between my "image" and "AHK", it is between "well recognized industry standards" and "AHK". Using the phrase "your own image" is simply to make the "well recognized industry standards" something that are not "well recognized industry standards", but rather only something I dreamed up. Sorry, these "well recognized industry standards" have been around for decades, probably before you even thought of being a programmer. I didn't dream them up, I use them in various languages that have implemented these "well recognized industry standards".

However lexikos, I want to make it clear that I think AHK, even with it quirks (deviations from recognized industry standards), is an outstanding product and I greatly appreciate all those who developed it and continue to make it better.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Class Static Variable assess

20 Feb 2017, 11:22

@ RFM, how about this?
Inconsistency with well recognized industry standards does not constitute a bug.
Here is are some perfect examples of inconsistency,
RFM wrote: I made it clear throughout the post that is it NOT my "own image of how the language should be"
RFM wrote: When I go from one language to the next, I've always been able to count on things in a class working the same, and they do, though the implementation my be different. AHK does some quirky things when it comes to classes, things you don't find in other languages, and things that are not in compliance with the behavior generally expected of classes. So, when I implement a class in AHK the way I would in any other language, I initially expect it to function as it would in any other language.
RFM wrote: Yes, I'm for real. I've learned to never presume anything, and to always get written confirmation, ALWAYS!!!.
Source
Now, after being rude enough, I agree on Error: Duplicate declaration being slightly disturbing. Also, I think it is great that you bring up some of these question/issues, I think many of us learn from it.

Good luck.
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Class Static Variable assess

20 Feb 2017, 11:35

guest3456 wrote:But you already know it all, so you will continue to be confused while writing multiple paragraph posts condescending AHK's design and everyone else who responds to you.
^
:clap:

i can read the future. i should buy a lottery ticket

guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Class Static Variable assess

20 Feb 2017, 11:36

RFM wrote: My comparison is NOT between my "image" and "AHK", it is between "well recognized industry standards" and "AHK". Using the phrase "your own image" is simply to make the "well recognized industry standards" something that are not "well recognized industry standards", but rather only something I dreamed up. Sorry, these "well recognized industry standards" have been around for decades, probably before you even thought of being a programmer. I didn't dream them up, I use them in various languages that have implemented these "well recognized industry standards".
please cite your source for "well recognized industry standards". you cant. just because a few languages use the same method doesn't make it a 'standard'. thats like staying "strict variable typing is a well recognized industry standard, therefore AHK diverges from standards". just lol.

therefore, these 'standards' are in fact something you dreamed up.
Spoiler
RFM wrote: In all languages I've worked with classes in,
exactly. stick to that wording, instead of making up 'industry standards'

RFM wrote:Can you show me another language that takes code equivalent to this:
static Cnt := 3 ; Scope: static class variable.
this.Cnt += 1 ; Scope: instance variable of class.
this.Cnt += 1 ; Scope: instance variable of class.
that results in this.Cnt being = 5 (the instance variable) and className.Cnt = 3 (the static variable)
I can show you another language:
https://developer.mozilla.org/en-US/doc ... type_chain

1. Right click in Chrome page, choose Inspect, Console tab
2. Type in each line and press enter:

Code: Select all

var a = {cnt: 3};
var b = Object.create(a);
console.log(a.cnt);
console.log(b.cnt);
b.cnt++;
b.cnt++;
console.log(a.cnt);
console.log(b.cnt);
also, feel free to experiment 'reversing the order' as in your OP:

Code: Select all

//b.cnt++;
//b.cnt++;
a.cnt++;
b.cnt++;
//or
b.cnt++;
a.cnt++;

we'll all be awaiting your apology for your rambling and bolding. although, given your hard headedness, its more likely you'll either 1. double down and argue further, or 2. save face and delete your acct never to be seen again

RFM
Posts: 28
Joined: 21 May 2016, 12:50

Re: Class Static Variable assess

20 Feb 2017, 14:42

RFM wrote: ... high caliber languages used to develop sophisticated robust software. I know of no other language that strays from what is well documented and commonly accepted standard of class functionality. Can you show me another language that takes code equivalent to this:
static Cnt := 3 ; Scope: static class variable.
this.Cnt += 1 ; Scope: instance variable of class.
this.Cnt += 1 ; Scope: instance variable of class.
that results in this. Cnt being = 5 (the instance variable) and className.Cnt = 3 (the static variable)
Sorry, I made the assumption that those that read the above would realize that I'm speaking of languages that run directly in the same environment as AHK, and in whose environment that language runs in, AHK can also run in, natively, being able to do the same things as that language. Otherwise, you are comparing apples and oranges. Especially if the environment the language runs in is exclusive to that language, meaning, no other language runs in that environment, therefore giving that language a monopoly, and any monopoly can do as it pleases for no one can choose any other. Such a language is not under any pressure to conform to industry standards. Since AHK runs directly under the operating system, interpreted or compiled, so must the other language. Its only host is the operating system.

I hope this clears things up. Its sad I have to take a paragraph to spell this out. So, again I ask: Can you show me another language of the high caliber languages used to develop sophisticated robust software that does as stated above? I'm not saying there are not any, just I've never encountered them.
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: Class Static Variable assess

20 Feb 2017, 15:07

guest3456 wrote: we'll all be awaiting your apology for your rambling and bolding. although, given your hard headedness, its more likely you'll either 1. double down and argue further, or 2. save face and delete your acct never to be seen again
so, #1 then.

RFM wrote: Such a language is not under any pressure to conform to industry standards.
as has already been shown, the 'industry standards' are only those that you've made up in your head. but well done in ignoring the request for citation of such standards, when you know you can't provide them.

RFM wrote: Since AHK runs directly under the operating system, interpreted or compiled, so must the other language. Its only host is the operating system.
since you seem to be oblivious to how modern programming languages work:
google Node.js
it runs completely server-side. since you dont like web browser, download the Node interpreter for windows, and then type in the code above

or how about this: the VS Code editor is a native Windows application written by Microsoft, in javascript:
https://code.visualstudio.com/

or just stfu and stop arguing, and instead start reading the links that are provided to you. such as the first wikipedia link i posted in this very thread, and you'll find other examples yourself.

Helgef already caught you in a lie, where you claimed that you "never presume anything", yet that's all that you've done non stop. you could've just come with the attidude of "help me understand how to do this" which inspires people to help you. instead you come in with your arrogance of "i presume its supposed to work this way, and it doesnt. therefore your langauge is buggy"

i'm of the opinion that better documentation would help with this sort of confusion. i think that Mozilla link is done well. but of course writing docs takes time and effort and someone has to devote that time to do it

lexikos
Posts: 9589
Joined: 30 Sep 2013, 04:07
Contact:

Re: Class Static Variable assess

20 Feb 2017, 22:10

You're clearly not interested in considering any point of view other than your own, so why should we?
RFM wrote:Sorry, I made the assumption that those that read the above would realize that I'm speaking of languages that run directly in the same environment as AHK, and in whose environment that language runs in, AHK can also run in, natively, being able to do the same things as that language.
There is no reason to make that distinction. If JavaScript doesn't count, then neither do any of the other languages you've used.

JavaScript can in fact be used to do almost everything that AutoHotkey can do, with the help of AutoHotkey itself, or with other (ActiveX/COM-based) libraries.

JavaScript is more relevant than most languages, because it (and Lua) heavily influenced AutoHotkey's object design.
Such a language is not under any pressure to conform to industry standards.
There are international standards defining how the EcmaScript/JavaScript language should behave, and each implementer is indeed under pressure to conform. Though I suppose some of them influence the standards to begin with.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: ht55cd3, OrangeCat and 314 guests