objects/object classes: new features from a newbie-friendly perspective

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

objects/object classes: new features from a newbie-friendly perspective

30 Dec 2017, 01:17

[EDIT:] these ideas are simplified and better-presented in the 2nd post on this thread

tl;dr: consider wish list ideas for AHK and objects from a newbie perspective (cf. only the expert perspective)

- I've seen small number of users on this forum get quite involved with custom AHK classes, it's the one area of AutoHotkey I've not been too enthused by, whereas usually I like to get involved in the detail.
- Occasionally I see people engage in the joy of the detail, that I often do for other areas of AutoHotkey. A good example of this is this thread:
Code Puzzle Thread - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 17&t=25683
- Because object classes are one of the least newbie-friendly things in AutoHotkey, while the move towards AHK v2 has shone a spotlight on virtually every area of AutoHotkey from both beginner and advanced perspectives. I don't feel that objects/object classes are getting the same attention. Only technical details appear to be really being reflected upon. E.g. here thoughts re. objects are more top-down than bottom-up.
v2-thoughts
https://autohotkey.com/v2/v2-thoughts.htm
- The one exception has been to treat key names that look numeric as numeric, which I believe is the right assumption to make. Although this would mark a major loss of generality, if there isn't some workaround to still create key names that look numeric, stored as strings. I'm somewhat concerned by the lack of discussion re. this point. Are there potential problems if this functionality were unavailable, e.g. perhaps relating to cloning COM objects, or with arrays in AHK v1 that wouldn't work in AHK v2.
- Another simple change is to clear objects when a for loop completes.
- People have mentioned: checking if an array contains an item, getting an item count in an associative array, listing/editing the items within an object via a GUI. Considering simple but common functions for manipulating the items in array, list manipulation, the numbers could increase quite rapidly, to a dozen without much effort. E.g. functions to sort linear arrays or remove duplicate items.

- By not bridging the simple and the complex, I believe that the use of objects within the AutoHotkey Community, could grow far slower than it otherwise would. I will make some points that lie in the middle ground. These are not wish list requests as such, just areas for consideration. If the ideas don't sound too exciting to any object experts, then it's even more important to consider them closely.
- StrSplit to an associative array. Then you can use HasKey to check that an array contains an item.
- Converting two objects to a binary/text representation, to query if they are identical.
- For loop in the reverse direction.
- Multiple enumerators for the same object: e.g. list the alphabet: forwards, backwards, vowels first, consonants first.
- Arrays that are sorted case sensitive/by date created, by default, and/or using these as additional enumerators (i.e. sorted only when needed).
- Allowing an associative array to use literally any string without interfering with methods. Otherwise using a prefix character, that no method begins with, is a good solution, but this looks odd.
obj.HasKey() fails for all keys if a key called HasKey exists - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 15#p148015
- Getting the parent of an item, parent information stored with the key, perhaps a custom class.
- A class to allow a 'for a to b step c' loop.
- Getting the original case of a key in an associative array, without doing a for loop.
- Optimisation for handling associative arrays that have no data, where only the key names matter, i.e. the equivalent of comma-separated lists.
- Making it clear when to use, and when not to use, ObjAddRef/ObjRelease.
- Behind-the-scenes information, e.g. if obj.a versus if obj.HasKey("a"), which is more costly, and by how much?
- A Length() method for a RegExMatch object, so they can be treated more like arrays in certain contexts. [EDIT:] Perhaps normal arrays should have Len() available, as well as Length().
- Why are RegExMatch objects read-only? There are circumstances where it would be convenient to edit the array, and thus a cloning method would be useful.
- Get/Set have access to a key's ancestry, but not Call, limiting what Call can do.
- ... Is it possible to have a class definition where you create an object, but the object doesn't just have keys, it has separate objects that 'belong' to it, but that aren't subkeys of it. A workaround might be a class that gives each object it creates, a unique ID number, and one static object inside the class definition, stores a separate array for each object.
- ... What if you want to, in effect, use Get/Set (used only for keys that don't exist) even when the key already exists, a workaround would be to put objects somewhere else, mentioned above. One reason for interest would be that Get/Set retrieve more information than Call, mentioned above.
- Does it matter if I leave a hundred 10-key arrays in my script, without clearing them.
- What are the most likely/worst problems that can happen when you don't release objects.
- What are window groups behind-the-scenes, something object-like?
- Is it possible to create a class that excludes certain keys from being enumerated by the for loop.
- Are variadic functions with all ByRef parameters possible.
- An efficient way to check that no keys in a linear array contain a certain string. An efficient way to find multiple unused characters, for use as delimiters/separators. This kind of problem would lead me to consider an object where you could retrieve a pointer for the start/end of the address in memory (with padding bytes either allowed or disallowed), you could then perform a binary search for unused characters.
- Can for loops be based on an infinite list of items.
- [EDIT:] I know there was some surprising behaviour relating to the use of () and [], I think it was this. These are equivalent apparently. It isn't a problem as such, but perhaps a script to identify such lines so that the user can make usage consistent would be useful. Also, it did cause me quite a bit of confusion until I realised what was going on.
Objects
https://autohotkey.com/docs/Objects.htm
obj.item(x) := y
obj.item[x] := y
v2-thoughts
https://autohotkey.com/v2/v2-thoughts.htm
•x.y(...) := z is equivalent to x.y[...] := z for all objects
...
•COM objects allow x.y(...) and x.y[...] to invoke a method or a property with parameters
- [EDIT:] A collection of simple examples for __Get/__Set/__Call, __New, _NewEnum, Next, base, __Delete, __Class, __Init.
- An official list of methods somewhere in the documentation. E.g. an attempt:
obj.HasKey() fails for all keys if a key called HasKey exists - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 55#p147755
- [EDIT:] Note: A key concern is that by anticipating demands, AutoHotkey would be easier to add to in future, and less likely to require script-breaking changes.
- Thanks for reading.

[EDIT:] Further points:
- To have a key with a value and subkeys at the same time.
- Objects with previous/next methods.
- (I will investigate creating some classes that can make possible some of these ideas.)
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
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

23 Apr 2018, 02:51

AUTOHOTKEY OBJECT IDEAS
scene-setting INTRODUCTION that got longer than I wanted it to be
[EDIT:] The 4 'POTENTIAL MAJOR CHANGE' sections edited.

POTENTIAL MAJOR CHANGE: LOOP AND DELETE
- The ability to retrieve keys in reverse order (and simultaneously delete them).

POTENTIAL MAJOR CHANGE: NUMERIC/STRING KEY NAMES
- Key names: integer keys: always numeric/always string/can be either.
- Or perhaps ObjRawGet/ObjRawSet could handle these. E.g. to store hex values as string key names, and retrieve them in the correct order in a for loop.
- In this example I have to add prefixes to retrieve the items in the correct order and avoid clashes with method names e.g. HasKey (see 'KEYS/METHODS WITH THE SAME NAME' below also).
- Basically at present I feel that you have to add prefixes to key names whenever you use associative arrays, this clutters the code a bit and is newbie-unfriendly. Perhaps some solution can be found.
I want to scan a given region for the 6 most common colors - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 30#p214830

Code: Select all

oArray := {}
Loop, Parse, vOutput, % ","
	if oArray.HasKey("z" A_LoopField)
		oArray["z" A_LoopField]++
	else
		oArray["z" A_LoopField] := 1
;frequency count for pixel colours (BGR)
vOutput2 := ""
for vKey, vValue in oArray
	vOutput2 .= vValue "`t" SubStr(vKey, 2) "`r`n"
Clipboard := vOutput2
MsgBox, % vOutput2
return
POTENTIAL MAJOR CHANGE: KEYS/METHODS WITH THE SAME NAME
- Allow keys(/properties) and methods to simultaneously exist that have the same name. This would be newbie-friendly, avoid a lot of problems (e.g. HasKey), and allow great flexibility, it would also avoid the need for certain ugly/complex classes that tried to achieve similar outcomes by roundabout means.
- Note: variables and functions can have the same name.
- Commonly I want to store text items/lines of text as keys in associative arrays, e.g. to remove duplicates, or for use as spell lists, but I have to add a prefix to avoid clashes with method names. This significantly impacts on the ease of using arrays as they exist at present for writing quick scripts. And requires careful explanations to avoid newbies making mistakes.
- A custom case-insensitive dictionary object class could solve the problem, however, this bloats any attempts at quick scripts. I'm not sure if I'd want a separate built-in dictionary object in AutoHotkey, perhaps not if it can be avoided.

POTENTIAL MAJOR CHANGE: STORE DATA: GET/SET/CALL - OR - HIDDEN OBJECT
- The ability to intervene every time a key/method is accessed (gotten/set/called). At the moment this only occurs when the key/method doesn't already exist.
- Or to make it easier to have a 'hidden object' inside the object or its base to store the data.
- Get/set can occur every time a key is gotten/set by one of the following:
-- store data for all objects of a particular class in the class object
-- store data in a global object
-- if a property would take precedence over a key with the same name: the store object would be a subkey, __Get/__Set would populate the subkey, attempts to get/set the subkey itself would be intercepted by a property (with the same name as the subkey), a custom enumerator would be used in a for loop [it may also be desirable to override the property with a key]
-- perhaps the store object could be stored in the base object for an object
-- some other new idea, concept

RELEGATED IDEAS (THAT COULD BE ACHIEVED VIA CUSTOM CLASSES)
(BUT WITH IMPORTANT FUNCTIONALITY TO POTENTIALLY CONSIDER/FACILITATE)
- Localised v. centralised objects. Terms that I just coined. For obj.a.b.c.d.e: if d exists, but e doesn't exist: ask either d or obj what to do when getting/setting a key or calling a method. (The object would have access to the path of the existent/non-existent key/property/method, up to the object itself.)
... [A potential idea could be that when an object adds a child object, (if the relevant mode is set to on) the child object inherits information about the parent object, and stores it in the base object, and so the child object uses methods from the parent/original ancestor object.] [EDIT: Something reusable like this to create an object of the same type would be useful: obj.key := ObjNew(obj)] [EDIT: Or just: obj.key := new (obj), obj.key := new (class), where class as a blank string would use a default object.]
[EDIT: Actually, obj := new %class%, obj := new %class%(arg1, arg2) already exist, so perhaps ObjNew is not needed.]
- Store order information: alphabetical order/date order/both, for use with for loops. This is partly with handling JSON in mind.
- Key names: case sensitive/case insensitive. [For me personally, case-sensitive objects wouldn't be necessary, as a Scripting.Dictionary object could be used instead.]
- Family trees: the base object stores the object parent's address. That way you can get both an object's children and parent. A mode switched to 'on' would automatically store the address.
... Family trees: the base object can store a 'string'/'label' for the object. I.e. objects can have both a string/numeric value and child objects.

ALSO (MINOR POINTS)
- The ability to get the nth item in an associative array. [I'm not sure how useful this would be, although being able to retrieve the key/value of the last key, would be useful.]
- I'm not quite sure if this would be sensible to implement or necessary, but: a list of keys to be excluded from a for loop. [This is partly as a fix if you couldn't do this: 'The ability for an object to store another object within its base, to store information that doesn't interfere with the keys.'] It could be something that is stored in the base object, or an option for a for loop.

OTHER USEFUL FUNCTIONALITY NOT RELATED TO THE NATURE OF OBJECTS
- The ability to get an upper bound for the total string length of all key names/values/both, e.g. prior to using a built-in/custom StrJoin.
- Objects to/from JSON. Save/create objects via a JSON string.
- The Sort function to be able to handle linear arrays: to sort and remove duplicates.
- ObjHasKey to be able to output the key name with the correct case. [Useful for spelling lists.][EDIT: I know the key name exists, but what is its case.]
- The ability to have variadic functions with ByRef variables. [Using ByRef variables is faster, and it would allow you to modify the input variables.]
- Allow both: Obj.Length() and Obj.Len(). [I find .Length() very hard to type at speed, and even when I use a hotstring, it slows me down. Partly it's because of how 'ngth' are arranged on a qwerty keyboard, and partly it's because of the prevalence of 'ght' words in English causing cognitive conflict.]
- Allow A_LoopField in a for loop: for vKey, A_LoopField in oArray, this would make it easier to do quick edits to code, and interchange between parsing loops and for loops.
- File objects: oFile.ReadHex and the ability to search for hex.
- Set the File object's capacity in anticipation of multiple small/large writes to it. [EDIT: I.e. set the length and capacity.]

BACKGROUND INFO
- What happens when the script ends but the ref count of an object is wrong?

Thanks for reading.
Last edited by jeeswg on 27 Jul 2018, 17:44, edited 7 times in total.
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: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects/object classes: new features from a newbie-friendly perspective

01 May 2018, 11:49

I think many of these are already possible by using specific workarounds:
- Localised v. centralised objects. Terms that I just coined. For obj.a.b.c.d.e: if d exists, but e doesn't exist: ask either d or obj what to do when getting/setting a key or calling a method. (The object would have access to the path of the existent/non-existent key/property/method, up to the object itself.)
Just use obj["a","b","c","d","e"] if you want to invoke the get meta function of obj. Use obj.a.b.c.d.e if you want to access each child object.
You simply need to understand that using . and [] has different implications.
- The ability to retrieve keys in reverse order (and simultaneously delete them).
This would be possible using a custom enumerator.
- I'm not quite sure if this would be sensible to implement or necessary, but: a list of keys to be excluded from a for loop. [This is partly as a fix if you couldn't do this: 'The ability for an object to store another object within its base, to store information that doesn't interfere with the keys.'] It could be something that is stored in the base object, or an option for a for loop.
Once again a custom enumerator.
- The ability for an object to store another object within its base, to store information that doesn't interfere with the keys.
Isn't that completely possible already?
- Set the File object's capacity in anticipation of multiple small/large writes to it.
Just set the files length: file.length := capacity?

Others are already in planning:
- Allow keys(/properties) and methods to have the same name. This would be newbie-friendly, avoid a lot of problems, and allow great flexibility, it would also avoid the need for certain ugly/complex classes that tried to achieve similar outcomes by roundabout means. It would also avoid the need for creating a separate dictionary object type.
( Why does this make you use a dictionary object? )
- The ability to get the nth item in an associative array. [I'm not sure how this useful would be, although being able to retrieve the key/value of the last key, would be useful.]
This would be useful to write custom enumerators.
- The ability to have variadic functions with ByRef variables. [Using ByRef variables is faster, and it would allow you to modify the input variables.]
Lexikos told me that he is planning to implement this.

For others the use gained is so minimal that implementing them isn't worth it:
Any time you talk about "alternative modes" either for objects integers in objects or whatever else
Adding a new seperate mode is only extra work for all involved people and creates borders - alternative modes should only get removed not added.
- Store order information: alphabetical order/date order/both, for use with for loops. This is partly with handling JSON in mind.
The information of order is not maintained within the object structure. Maintaining it would essentially mean adding an extra field to each field doubling the current fields and the time it currently takes to access those objects.
- The ability to get an upper bound for the total string length of all key names/values/both, e.g. prior to using a built-in/custom StrJoin.
Having join itself is a lot more useful.
- Objects to/from JSON. Save/create objects via a JSON string.
While that is not exactly uncommon I think it's a lot of work to do completely consistent since AHK objects are not completely compatible with the JSON standard.
Also there are good libraries - why not use them?
- ObjHasKey to be able to output the key name with the correct case. [Useful for spelling lists.]
A key can be many things including but not limited to strings.
Why would you want something special only for one subtype?

I didn't understand these completely:
- Family trees: the base object stores the object parent's address. That way you can get both an object's children and parent. A mode switched to 'on' would automatically store the address.

- Family trees: the base object can store a 'string'/'label' for the object. I.e. objects can have both a string/numeric value and child objects.
I think you sometimes use objects where you should use classes and vice versa.
There are some decent suggestions inside though.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

01 May 2018, 16:39

- Thanks very much for your feedback nnnik.

KEY/PROPERTIES SAME NAME
- Is it unusual to allow keys and properties to have the same name?
- Because key/property names could clash, e.g. frequency counts/spell lists, you need a prefix character in key names, and you then need SubStr when doing a for loop.
- You also need a prefix to store/retrieve hex integers in the right order. (A reason for the integer key names always/optionally stored as strings mode.)
- I find the regular need for prefixes, in almost anything related to associative arrays, a bit ugly and inconvenient, and a bit off-putting for newbies, it makes the simple look complex.
- A dictionary object type would be one solution, but perhaps better: allowing any key name you like, i.e. no clashes with method names.

OTHER POINTS
- Localised/centralised. obj["a","b","c","d","e"] and obj.a.b.c.d.e. Potentially a mode might make these act identically.
- Localised/centralised. A mode might also mean that obj.a := {} would automatically make that child object of the same class as the parent. It's fiddly and inflexible to always have to use 'new', and it's easy to forget also.
- Loop and delete. If I want to loop through an object, and delete keys as I go along, so far the best workaround is to either record the key names to delete, and delete them afterwards, or, to create a new array with the keys to keep. This kind of thing is a common activity.
- HIDDEN KEYS. Keys to hide from a for loop. To hide away keys needed internally, but not intended for display. Perhaps an exclude mode and an exclude list object could be stored in the base object. A better idea might be that each object could have access to a 'hidden' object that it can access but that is inaccessible via obj.key.
- HIDDEN KEYS. What is the best way to store information in an object, that is not accessible via obj.key?
- File object, Length property. I tried setting oFile.Length in advance, but got no improvement in speed. Also, if I overestimate the capacity, I'm not sure how to reduce it, so that the file ends where the text ends, i.e. no sparse files.
- Modes. Modes are a way to have various custom built-in classes/object variants. One reason for modes is to add restrictions to arrays to make them behave like in other programming languages.
- Keys, order added. It's a fundamental feature request, it would be useful with JSON for example. Storing the date order would be an optional mode. (The speed of objects is fast, halve the speed, still fast.)
- JSON. How would AHK objects be incompatible with JSON? AHK could benefit from a built-in way to preview objects as a string, and to save an object to disk, and JSON would be a way. (The benefits of a basic/more extensive built-in library to read/write JSON for Internet use would be welcome, but were not my intention.)
- ObjHasKey. I'm not sure what you meant. The prototype ObjHasValue function can return a key, ObjHasKey could have this ability also. (E.g. I know 'key' exists but what is its case? key/Key/KEY.)
- Family trees. This is very basic, more a way of thinking than a feature request. I and others have been surprised that objects can have child objects *or* a string value, but not both, and that you can get an object's children but not its parent. A solution would be a mode that automatically creates child objects with Label() and Parent() methods (or other names).

- Btw is there anything that stands out to you as being more complicated to implement? Thanks.
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: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects/object classes: new features from a newbie-friendly perspective

02 May 2018, 00:26

As I said before no seperate "alternative modes" are ever going to happen due to:
Them putting borders between developers and them being a high cost at implementation.
Therefore you can cross out:
- You also need a prefix to store/retrieve hex integers in the right order. (A reason for the integer key names always/optionally stored as strings mode.)
- Localised/centralised. obj["a","b","c","d","e"] and obj.a.b.c.d.e. Potentially a mode might make these act identically.
- Modes. Modes are a way to have various custom built-in classes/object variants. One reason for modes is to add restrictions to arrays to make them behave like in other programming languages.
- Localised/centralised. A mode might also mean that obj.a := {} would automatically make that child object of the same class as the parent. It's fiddly and inflexible to always have to use 'new', and it's easy to forget also.
This will never happen due to objects containing other objects for completely different purposes - and the purpose your suggesting for this syntax is not even among those.
- HIDDEN KEYS. Keys to hide from a for loop. To hide away keys needed internally, but not intended for display. Perhaps an exclude mode and an exclude list object could be stored in the base object. A better idea might be that each object could have access to a 'hidden' object that it can access but that is inaccessible via obj.key.
Didn't I tell you to use a custom enumerator?
- Is it unusual to allow keys and properties to have the same name?
No it's impossible to differentiate the intent to access the key or a property.
- ObjHasKey. I'm not sure what you meant. The prototype ObjHasValue function can return a key, ObjHasKey could have this ability also. (E.g. I know 'key' exists but what is its case? key/Key/KEY.)
No neither ObjHasKey nor ObjHasValue return a key. ObjHasValue would at most return an array containing a key or keys.
- I find the regular need for prefixes, in almost anything related to associative arrays, a bit ugly and inconvenient, and a bit off-putting for newbies, it makes the simple look complex.
You are doing something wrong - I never need them.
- Keys, order added. It's a fundamental feature request, it would be useful with JSON for example. Storing the date order would be an optional mode. (The speed of objects is fast, halve the speed, still fast.)
The simple halfing of one of the elements can result in a 20 times slower program. Program it yourself and it'*s no basic request either.
- JSON. How would AHK objects be incompatible with JSON? AHK could benefit from a built-in way to preview objects as a string, and to save an object to disk, and JSON would be a way. (The benefits of a basic/more extensive built-in library to read/write JSON for Internet use would be welcome, but were not my intention.)
JSON has several restrictions e.g. it has no simple way of adding back references. Also we wouldn't be able to store funcs and alike.
- Family trees. This is very basic, more a way of thinking than a feature request. I and others have been surprised that objects can have child objects *or* a string value, but not both, and that you can get an object's children but not its parent. A solution would be a mode that automatically creates child objects with Label() and Parent() methods (or other names).
I cannot help but feel that you simply do not understand objects at all. Can a variable contain both a string and an object? There is no difference between how a string is stored or an object is stored. They take up the same space.


- HIDDEN KEYS. What is the best way to store information in an object, that is not accessible via obj.key?
Store them in a seperate object.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

02 May 2018, 04:30

- I wouldn't get hung up on the word 'mode', there may be alternative ways to achieve these things, e.g. functions/methods. (Btw if certain ideas were implemented, they would provide new workaround possibilities for other ideas.)
- Re. 'use a custom enumerator', for that particular problem I preferred a fix *before* the for loop stage, anyhow, the whole point of these suggestions is for common things to be built-in, custom enumerators 'need not apply'.
- 'impossible to differentiate the intent to access the key or a property'. Interesting. Really?
- In this proposal ObjHasValue returns a key ByRef:
Object.HasValue/Contains/KeyOf/FindValue - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 37&t=30536
Object.HasValue(Value [, CaseOrTypeSensitive, ByRef Key])
Perhaps you would quibble the use of the word 'return', since it's not the direct return value, if so, then how would you describe this succinctly?
- Prefixes in key names have their uses. If an object has keys/methods with the same name, you can have a problem. Even if *you* use the object safely, a general user could run into key/method name clashes, and be stumped.
- Slow. Only if date order mode was on, would keys be returned/stored in date order. (There's no point complaining that certain functionality would require execution time, if you *need* that functionality.)
- 'do not understand objects at all'. Imagine someone was drawing up a family tree, but none of the people were assigned names, because 'you can have a value or children but not both'. Since I understand how objects currently work, I accepted the 'cannot have both' principle as an axiom, and suggested a workaround. This principle *surprises* people when they first encounter it.
- 'Store them in a separate object'. I'd need a different or fuller answer than that, I will start a thread re. this, I had been considering such a thread anyway. Cheers.
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: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects/object classes: new features from a newbie-friendly perspective

02 May 2018, 05:11

- Re. 'use a custom enumerator', for that particular problem I preferred a fix *before* the for loop stage, anyhow, the whole point of these suggestions is for common things to be built-in, custom enumerators 'need not apply'.
I dont really see a need for it at all ( inverse enumeration might be a thing though. )
- 'impossible to differentiate the intent to access the key or a property'. Interesting. Really?

Code: Select all

class test {
	property[]{
		get{
			return [ "One", "Two", "Three", "Four" ]
		}
	}
}
t :=  new Test()
ObjRawSet( t, "property", ["Eins", "Zwei", "Drei", "Vier"] )
Msgbox % t.property[1] ;which value did I try to access here the property property or the array stored inside property.key
Im not quite sure myself what I wanted to access there - anyways you cannot see it easily.
- In this proposal ObjHasValue returns a key ByRef:
Object.HasValue/Contains/KeyOf/FindValue - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 37&t=30536
Object.HasValue(Value [, CaseOrTypeSensitive, ByRef Key])
Perhaps you would quibble the use of the word 'return', since it's not the direct return value, if so, then how would you describe this succinctly?
I see this might indeed be an option - it's easily implemented and can reduce costly additional lookups.
( Even though I dont think it won't be commonly used. )
- Prefixes in key names have their uses. If an object has keys/methods with the same name, you can have a problem. Even if *you* use the object safely, a general user could run into key/method name clashes, and be stumped.
As I said before lexikos will probably make it so that keys which are not methods but are called are ignored - therefore this problem will vanish.
- Slow. Only if date order mode was on, would keys be returned/stored in date order. (There's no point complaining that certain functionality would require execution time, if you *need* that functionality.)
Yes but it has many downsides which apply if you make it a mode and it is also costly. Implementing a second Object which does exactly the same as the normal object is just asking for trouble.
- 'do not understand objects at all'. Imagine someone was drawing up a family tree, but none of the people were assigned names, because 'you can have a value or children but not both'. Since I understand how objects currently work, I accepted the 'cannot have both' principle as an axiom, and suggested a workaround. This principle *surprises* people when they first encounter it.
When people first encounter functions they are also confused by many things around them - you would not change functions because of that or? Also the logic is that you have a parent object containing child objects - the name of the child object is not supposed to be in the parent object - it has nothing to do with the parent object.
- 'Store them in a separate object'. I'd need a different or fuller answer than that, I will start a thread re. this, I had been considering such a thread anyway. Cheers.
OK I have few standard solutions for this. Im willing to share them.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

02 May 2018, 15:45

- Keys v. methods. Oh, you gave an example of key v. *property*. I would suppose that the answer to that is that if both exist, one should always take priority (preferably properties), it appears that keys take priority, is this documented somewhere? Anyhow, I was interested in key/property v. *method*, can the object always distinguish between get/set and call.
- [EDIT:] If properties took priority over keys, I could use ObjRawGet/ObjRawSet to create an object called this.HiddenKey and store data there, and every time the user tried to get/set the value of this.HiddenKey, the property would get/set the value of this.HiddenKey.HiddenKey. For a for loop on 'this', the class would point you to a standard enumerator for 'this.HiddenKey'. This would be a way to achieve a lot of the functionality that I'm looking for.
- [EDIT:] (Furthermore if ObjRawGet/ObjRawSet, or some other functions, could allow you to use integer key names with a string type, that would allow you to return hex strings in the right order without a prefix having to be added to each key name.)
- Family trees. I mean simply that family trees illustrate a kind of data that people might want to store using multiple objects, objects that are similar to standard AHK objects, but where each object has parent and label methods. (The only information stored about child objects, would be that which AHK already stores.)
- Newbie misunderstandings. There are all sorts of misunderstandings that people can have, but two important ones are: surprise that objects can't have both a value and child objects (I seek a workaround via a 'label' method that stores a label for the object, or to perhaps store some information inside the base object), surprise that objects can't have both keys and methods with the same name (I might suggest that either this is made possible, or, an idea I'm not particularly keen on, that AutoHotkey have a dictionary object type).
- Hidden keys. I've started a thread re. 'What is the best way to store information in an object, that is not accessible via obj.key?'
object classes: storing data outside of an object - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=48335
- [EDIT:] Btw how do you feel about meta-functions? I actually never thought that they were that bad. I was surprised that you could only use get/set/call when keys/methods didn't exist cf. whenever a key/method was accessed. However, mostly I could still achieve what I wanted through workarounds. If they are to be removed, I'm not exactly sure why that would be, and what the benefits would be (although I trust that there are many). (Generally I've been interested in small tweaks/increases in functionality, which can often lead to many more things being possible.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects/object classes: new features from a newbie-friendly perspective

03 May 2018, 01:36

Hello :wave: .
I would suppose that the answer to that is that if both exist
Both exist, objrawset(obj,key,var) stores the key / value pair in obj. properties[] are stored in the class object.
one should always take priority (preferably properties), it appears that keys take priority, is this documented somewhere?
It is not about priority, but about which is found first, it is documented here: Objects (again).
[Meta functions,] If they are to be removed, I'm not exactly sure why that would be
Who said they where being removed?

Cheers.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects/object classes: new features from a newbie-friendly perspective

03 May 2018, 02:46

They are being changed at most.
Recommends AHK Studio
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects/object classes: new features from a newbie-friendly perspective

03 May 2018, 02:50

- Family trees. I mean simply that family trees illustrate a kind of data that people might want to store using multiple objects, objects that are similar to standard AHK objects, but where each object has parent and label methods. (The only information stored about child objects, would be that which AHK already stores.)
Is it your parents resposibility to remember your name or is it your own? Is the name an attribute of the parent or is it an attribute of the child.
What about the first object in the tree how would you store its name?

We cannot change how Objects work on such a fundamental level just because people are too stupid to understand them.
If you want such a family tree object create your own class.
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects/object classes: new features from a newbie-friendly perspective

03 May 2018, 04:24

If you want such a family tree object create your own class.
I think that applies to almost the entire thread, create your own class.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

03 May 2018, 10:27

- @Helgef: What do you mean by 'found first'?
I found this in the documentation:
assigning a value stores it in the object, effectively disabling the property
Is that what you meant? [Please always be specific re. objects, the subject is too complicated and prone to cause misunderstandings. Plus I could spend all day trawling through the object documentation.]
- Where I said 'If properties took priority over keys', this could allow a far better alternative to this:
object classes: storing data outside of an object - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=48335
My most serious classes need that kind of functionality. Let's assume that keys continue to take priority over properties as they do now, how could I improve that class?
- Meta-functions: simplified not removed, search for 'be simplified' above.
- Re. 'create your own class'. I made a list of things that ought to be considered fundamental or semi-fundamental, so, even if some of the functionality wasn't built-in, it should probably either: be listed in the documentation as an example, be easier to achieve than it currently is using built-in functionality. I've shuffled about my 2nd post a bit, to distinguish between things that I think should be built-in versus things I think should be easier.

- @nnnik: Re. family trees. An object stores its own name, and information about its parent.
- Here's a simplified example, I would use parent/label methods not keys (or perhaps store information in the base object).
- The general point is that sometimes with objects you want to be able to store information about an object *somewhere*, but to not clutter an object's keys.
- See my suggestion for ObjNew above.

Code: Select all

q:: ;objects with parent/label information
oArray1 := {}
oArray2 := {}
oArray3 := {}

oArray1.Label := "Array I"
oArray1.Child1 := oArray2

oArray2.Label := "Array II"
oArray2.Child1 := oArray3
oArray2.Parent := oArray1

oArray3.Label := "Array III"
oArray3.Parent := oArray2

;go down:
MsgBox, % oArray1.Label
MsgBox, % oArray1.Child1.Label
MsgBox, % oArray1.Child1.Child1.Label

;go up:
MsgBox, % oArray3.Label
MsgBox, % oArray3.Parent.Label
MsgBox, % oArray3.Parent.Parent.Label
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: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: objects/object classes: new features from a newbie-friendly perspective

03 May 2018, 12:14

Why is children not an array?
Also this should probably be a class with methods.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

09 May 2018, 12:37

- I've greatly improved by main (2nd) post above (taking into account the content below it):
objects/object classes: new features from a newbie-friendly perspective - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 83#p214283

- Methods v. keys. A test.

Code: Select all

q:: ;test methods/keys with same name
obj := new MyMethodOrKeyClass
MsgBox, % obj.MyKey ;key
MsgBox, % obj.MyMethod() ;method
ObjRawSet(obj, "MyMethodOrKey", "key")
MsgBox, % obj.MyMethodOrKey ;key
MsgBox, % obj.MyMethodOrKey() ;(blank)
return

class MyMethodOrKeyClass
{
	MyKey := "key"
	MyMethod()
	{
		return "method"
	}
	MyMethodOrKey()
	{
		return "method"
	}
}
- Family tree class. This is *approximately* what I'm aiming for.
- Obviously storing child objects inside an object is built-in, to me it seemed quite natural to also store parent information for each object *somewhere*, and a label for each object *somewhere*. I would want the parent/label information not to be stored inside the object as standard keys.
- A key feature is that when you do obj.key := {}, obj and obj.key should be of the same class, and obj.key should contain information about obj (its parent object).
- The basic principle is completely normal ordinary AHK objects, but where parent/label information is also stored.

Code: Select all

q:: ;family tree example
obj := new MyFamilyTreeClass("A1", "")
oTemp := obj
MsgBox, % "label: " oTemp.Label() "`r`n" "parent (addr): " oTemp.Parent() "`r`n" "parent (label): " Object(oTemp.Parent()).Label()

obj.key1 := {}
obj.key1.SetLabel("B1")
oTemp := obj.key1
MsgBox, % "label: " oTemp.Label() "`r`n" "parent (addr): " oTemp.Parent() "`r`n" "parent (label): " Object(oTemp.Parent()).Label()

obj.key2 := {}
obj.key2.SetLabel("B2")
oTemp := obj.key2
MsgBox, % "label: " oTemp.Label() "`r`n" "parent (addr): " oTemp.Parent() "`r`n" "parent (label): " Object(oTemp.Parent()).Label()

obj.key1.key1 := {}
obj.key1.key1.SetLabel("C1")
oTemp := obj.key1.key1
MsgBox, % "label: " oTemp.Label() "`r`n" "parent (addr): " oTemp.Parent() "`r`n" "parent (label): " Object(oTemp.Parent()).Label()
return

global oGlobalStore
MyDataStoreClassInit()
{
	static vDummy := MyDataStoreClassInit()
	oGlobalStore := {}
}
class MyFamilyTreeClass
{
	__New(vLabel, vParent)
	{
		vAddr := &this
		if !oGlobalStore.HasKey(vAddr)
			oGlobalStore[vAddr] := {}
		oGlobalStore[vAddr, "Label"] := vLabel
		oGlobalStore[vAddr, "Parent"] := vParent
	}
	__Set(vKey, vValue)
	{
		if IsObject(vValue)
		{
			vParent := &this
			ObjRawSet(this, vKey, new MyFamilyTreeClass("", vParent))
			for vKey2, vValue2 in vValue
				this[vKey, vKey2] := vValue2
			return
		}
	}
	Label()
	{
		vAddr := &this
		return oGlobalStore[vAddr, "Label"]
	}
	Parent()
	{
		vAddr := &this
		return oGlobalStore[vAddr, "Parent"]
	}
	SetLabel(vLabel)
	{
		vAddr := &this
		oGlobalStore[vAddr, "Label"] := vLabel
	}
}
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
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

13 May 2018, 00:34

Did you know that these are possible?

Code: Select all

obj := new %class%
obj := new %class%(arg1, arg2)
Unfortunately there isn't a way to specify a standard array AFAICS, although I suppose you could create a custom array with the same properties as a standard array.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects/object classes: new features from a newbie-friendly perspective

13 May 2018, 01:40

Is that what you meant? [Please always be specific re. objects, the subject is too complicated and prone to cause misunderstandings. Plus I could spend all day trawling through the object documentation.]
No. I'll be as clear or unclear as I like. Evidently, you should.

Code: Select all

obj := new %class%
Any* operator can operate on a dynamic variable reference, assuming that is what that is supposed to be. In v2 you can do %expr% :thumbup: . I almost never do though.

*(unless documented not to (member access for example)) Edit: Strike, irrelevant and probably misleading and incorrect.
Last edited by Helgef on 13 May 2018, 11:19, edited 1 time in total.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

13 May 2018, 01:54

- @Helgef: What I meant is that sometimes you're a bit cryptic by choice, i.e. you leave things out for one of 3 reasons: (a) not to spoon-feed, so the person has to put in some effort, (b) because you think it's obvious to the person, (c) for a bit of mystery (before revealing the answer later).
- I'm fine with this 99% of the time, however, when it's a thread on the nature of objects, things get so convoluted that I prefer to keep things simple. And often, even when people try to be explicitly clear, there are still misunderstandings. And I'm still unclear on what you meant re. 'found first' (sorry).
- Unless, you, I, nnnik, and a couple of(/half-dozen) others, try and sort this out, objects are going to be locked to people (including me), locked like a locked forum thread.
- [EDIT:] What's at stake is this: I read through a tonne of documentation, trying to guess what was meant, I spend time on it, I try my best, I pick the wrong thing, and I have to ask again, typically I will misunderstand the second response, so I have to ask again for a third response. Spoon-feeding can be a good thing to do, and it's not just me who benefits from trying to make things easy re. objects.
- [EDIT:] Also, I have multiple threads re. objects, and I get sidetracked while preparing notes/tutorials, confirming whether the cryptic remarks were clarified later on.

- For new %class%, the class name is obtained from a variable call 'class'.
- For new %class%(arg1, arg2) or new MyClass(arg1, arg2), I see that as the new-style syntax for function names, rather than the old-style syntax for variable names.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: objects/object classes: new features from a newbie-friendly perspective

13 May 2018, 11:16

(a) sure, (b) perhaps, (c) no.
Intravenous feeding.
Regarding the order, it is well described here,
meta functions wrote:When the script gets, sets or calls a key which does not exist within the target object, the base object is invoked as follows:
[...]
Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects/object classes: new features from a newbie-friendly perspective

13 May 2018, 11:36

- @Helgef: Thanks re. searching for keys, i.e. 'chase the base'. You know, I forget some of these basics over time because there are *so many* basic points re. objects.
- (Re. 'abc', it pretty much describes how *I* operate anyway. Although, if a script has multiple fiddly elements, I often try to write a model script. 'Intravenous feeding', most amusing, I never associated that idea with 'spoon-feeding'.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: mikeyww and 144 guests