Objects

Discuss the future of the AutoHotkey language
lexikos
Posts: 6205
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Objects

13 Oct 2018, 18:55

Over the last 16 months, I have created a script library to test a number of ideas for potential changes to how objects work.

Object.ahk

Summary of changes implemented by the script:
  • Separate data and interface: array elements and properties/methods are separated, and generic objects do not have array elements by default.
  • Separate methods and properties.
  • Separate static and instance members.
  • New data types: Array (linear), Map (associative, type- and case-sensitive).
  • Meta-functions are replaced with new meta-methods, which work more like normal methods.
  • Different enumeration pattern: _NewEnum and Enumerator objects are replaced with __forin and function/closure objects (or an object with Call instead of Next).
  • Reduced multi-dimensional array support: Using multiple indices does not automatically create arrays of arrays.
  • New exception type hierarchy.
  • New error dialog with stack trace, formatting changes and a few shortcut buttons.
  • New object model:
    • Since static and instance members are separate, each class is split into the class itself (static members) and its prototype.
    • Each object (if under control of the library) ultimately inherits from Object.prototype.
    • Each class which extends Object is actually an instance of Class (i.e. inherits from Class.prototype).
    • Properties and methods can be defined by calling methods on an individual object or a class's prototype.
    • Methods are provided to test for the existence of a property or method.
See GitHub (link above) for code, documentation and details about some parts that haven't been implemented.

Using the script

Read the included documentation before using the script.

For basic use of the script, #include Object.ahk (including only this file should not interfere with existing code).
To enable alterations to Object(), {}, Array() and [], #include Object.Override.ahk.
To enable alterations to non-object values, #include Object.Values.ahk.
To enable the new error dialog, #include ErrorDialog.ahk (either include it in the auto-execute section or call OnError("ErrorDialog")).

To #include any of these files, do one of the following:
  • #Include by full/relative path.
  • Place files directly in a Lib folder and use #include <[i]name[/i]> without .ahk.
  • Place files in Lib\Object and use #include <Object\[i]name[/i]> without .ahk.
There are a few requirements when using the script that are entirely due to technical limitations, and would not exist if these changes were built-in:
  • When defining a class, make sure it extends Object or a subclass of Object.
  • When defining a class, do not place properties or methods directly inside the class. Instead, place them inside nested classes class _instance or class _static as appropriate. The first time the class object is accessed or instantiated, these nested classes are automatically merged. These nested classes act as a substitute for a static keyword which could hypothetically be applied to any property or method (instance members would be defined by default).
  • To define a property and method with the same name (not recommended), create the property after the object is created (in __new or __initclass).
  • Data/array element access should be done through obj.Item[keyOrIndex] instead of obj[keyOrIndex], except with Array, which supports both. Custom collection classes can define an Item property with parameter(s).
  • To enumerate properties with for, use for propname, propvalue in [color=red]new Enumerator([/color]myObject.Properties()[color=red])[/color]. for cannot accept an enumerator function/closure directly with the current implementation. Follow the same pattern for any other explicitly-called enumeration methods (for instance, if someone defines a method that returns a reverse-order enumerator).
TODO
  • Replace SetCapacity, GetCapacity and GetAddress with a dedicated binary buffer type.
  • Fix Array so that setting Length to a larger value does not cause the new last element to incorrectly be marked as having a value set.
  • Other forgotten things.
Helgef
Posts: 3232
Joined: 17 Jul 2016, 01:02
Contact:

Re: Objects

15 Oct 2018, 03:49

Hello. I've only skimmed the documentation, but it looks like very diligent work, thanks for sharing.
Separate data and interface...
New object model
This is very appropriate, great :thumbup:.
Different enumeration pattern:
Excellent.

The error dialog looks great.

I look forward to look into this further and hear what others have to say.

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

Re: Objects

15 Oct 2018, 07:55

I've looked through this as well. Haven't had time to play with it.

I think some examples of how the new usage would work might be helpful. I still consider myself a novice when it comes to objects and OOP. I know what static and instance members are but I don't understand the difference between array elements and properties. To me, they seemed the same I guess.

Reading through some of the documentation on GitHub, it sounded as if you were thinking that different syntaxes would be used for properties vs. array elements.
Actual implementation: Meta-functions cannot currently differentiate between obj.x and obj["x"]; therefore, object types which contain data are expected to provide a parameterized property obj.Item[key]. Instances of Array also support myArray as the index must be an integer.


It seems like this is a great deal more complex than what we've had and potentially what we need. At least that's my very initial feeling without having a good understanding of how the usage of this would look like. I certainly want to but am just having a hard time wrapping my head around it all...
User avatar
nnnik
Posts: 3470
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Objects

15 Oct 2018, 08:07

I'd really like to see the effects of this. Sadly I currently don't seem to have the time to play around with it.
I'm hesitant to build anything major using this library but it would be the only way to really see the effects.
That being said every change seems to be perfect for me.

@kczx3
static are properties of your class.
They are not available to the instance other than through accessing the class itself.
I like this new addition because it adds a seperation where you were not able to seperate before.
Recommends AHK Studio
User avatar
kczx3
Posts: 666
Joined: 06 Oct 2015, 21:39

Re: Objects

15 Oct 2018, 08:12

I have put Object.ahk and Object.Errors.ahk in my lib folder and tried running the example found in Errors.md. It doesn't seem like the ErrorDialog is pointing to the right line though. The forum isn't letting me attach a png so here is the MsgBox's text.

---------------------------
Temp.ahk
---------------------------
Error in #include file "C:\Users\cgoepfrich2.MUNSON\Google Drive\AHK\AutoHotkeyV2\Lib\Object.Errors.ahk":
(TypeError) Invalid parameter #1

Specifically: twice (String)

Line#
660: if f := cls.←method["__initclass"]
661: f.call(cls)
662: }
001: {
002: Throw extype.new(p*)
003: }
009: {
---> 010: While (stk := Exception("", -A_Index-1)).What != -A_Index-1
011: if !(stk.File ~= "\\Object(?:\.\w+)?\.ahk")
012: if skip_frames-- <= 0
013: Break
015: ObjRawSet(this, "Message", '(' type(this) ') ' msg)
016: ObjRawSet(this, "Extra", Object_String(extra))
017: ObjRawSet(this, "File", stk.File)
018: ObjRawSet(this, "Line", stk.Line)

The current thread will exit.
---------------------------
OK
---------------------------
User avatar
kczx3
Posts: 666
Joined: 06 Oct 2015, 21:39

Re: Objects

15 Oct 2018, 08:15

@kczx3
static are properties of your class.
They are not available to the instance other than through accessing the class itself.
I like this new addition because it adds a seperation where you were not able to seperate before.
It sounds like you are describing private properties to me. Now that I think about it, I've typically only used the word static with methods in other languages like PHP and JavaScript.
User avatar
nnnik
Posts: 3470
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Objects

15 Oct 2018, 09:40

I don't know whether PHP or JavaSctipt has static attributes.
I only know static from Java - though I know of a few other languages that probably have it.

private is a variable thats inside an object or class and can only be acessed inside the scope of the object or class itself.
static is a variable that only exists within the class rather than any derived instances.
If my Bitmap class has the static method "screenshot" then calling it on the GDI class itself will make the screenshot.
Whereas calling it on a specific Bitmap will result in an error since it doesn't have this method.
Recommends AHK Studio
User avatar
kczx3
Posts: 666
Joined: 06 Oct 2015, 21:39

Re: Objects

15 Oct 2018, 09:50

Ok, thanks for the explanation!
lexikos
Posts: 6205
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Objects

16 Oct 2018, 03:00

I think some examples of how the new usage would work might be helpful.
Have you looked at the test cases (class Tests)? They're very arbitrary, but any examples I might come up with right now would be much the same.

Reading through some of the documentation on GitHub, it sounded as if you were thinking that different syntaxes would be used for properties vs. array elements.
Yes, I thought I made that clear.
Separate syntax for properties vs. array elements
  • Let obj.x and obj.x() access a property or method only.
  • Let obj[i] perform indexing, as defined by the object's class.
  • {a: b, c: d} is most often used to create ad-hoc objects with known properties, so these should be properties.
  • Provide some other way to access properties with calculated names.

It seems like this is a great deal more complex than what we've had and potentially what we need.
What's "this"?

Since you quoted the "Actual implementation" section, I'll point out that this applies specifically to the script and not the hypothetical built-in implementation. Mostly it is due to technical limitations of the current AutoHotkey build.

At least that's my very initial feeling without having a good understanding of how the usage of this would look like.
Mostly the usage would look like it does now, but each element of syntax would be given a more specific purpose. Where before arr[i] and obj.prop could both access an array element or property or return a method reference, in future arr[i] would only ever access an array element and obj.prop would only ever access a property.

The basic philosophy is that breaking the object model into smaller (even if more numerous) pieces makes the individual components simpler, easier to understand and use, and less error-prone.
lexikos
Posts: 6205
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Objects

16 Oct 2018, 03:23

I have put Object.ahk and Object.Errors.ahk in my lib folder and tried running the example found in Errors.md. It doesn't seem like the ErrorDialog is pointing to the right line though.
I downloaded a fresh copy of the repository (as a zip), extracted, renamed the "Object.ahk-master" folder to "Lib", copied the ding() example into the parent directory and added #Include <Object> (above or below the example). The error dialog pointed at ding("twice").

I did not use ErrorDialog in this test because the MsgBox text you posted is clearly from the standard dialog. Did you follow the instructions?
To enable the new error dialog, #include ErrorDialog.ahk (either include it in the auto-execute section or call OnError("ErrorDialog")).
ErrorDialog points at the same line as the standard dialog, unless you change the script file after loading it. For either dialog to point at the line you indicated, Exception() must fail to return an appropriate What/File combination. This would happen if you compile the script, since the (debugging) call stack is not available. It would also happen if every stack entry for the current thread is somehow inside an Object.ahk or Object.something.ahk file, such as if you name your main script file that way.

Make sure you have v2.0-a100, as I only test with the latest alpha.
User avatar
kczx3
Posts: 666
Joined: 06 Oct 2015, 21:39

Re: Objects

16 Oct 2018, 08:17

Have you looked at the test cases (class Tests)? They're very arbitrary, but any examples I might come up with right now would be much the same.
I did briefly look at that file earlier. I took another look again and frankly, I just think that it is above my head. I struggle with that kind of abstract/arbitrary code. Thanks for pointing me to it though.
What's "this"?
I just meant all of the changes outlined in your post. Again, I think that the implementation is just above my head.

Your below comment makes me seem less concerned though.
The basic philosophy is that breaking the object model into smaller (even if more numerous) pieces makes the individual components simpler, easier to understand and use, and less error-prone.
Regarding the new ErrorDialog, it appears the issue was because I was using ahk-v2-a99. Updating to a100 now points to the correct line.
iseahound
Posts: 326
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: Objects

27 Oct 2018, 06:10

Quick question: how fast do you expect the pure data objects to be? As fast as associative arrays? c?

Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 6 guests