function objects example

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

function objects example

01 Dec 2019, 00:08

This example isn't working on AHK v2-a107:
Function Objects - Definition & Usage | AutoHotkey v2
https://lexikos.github.io/v2/docs/objects/Functor.htm#User-Defined-Examples

Also, was there a reason that
obj.method("foo", "bar")
was changed to:
%obj.method%("foo", "bar")

Although shouldn't both work? (The former worked if I modified functions One and Two in the example.)

Link:
Change examples to use .new() (closes #391) · Lexikos/AutoHotkey_L-Docs@3d73cd3 · GitHub
https://github.com/Lexikos/AutoHotkey_L-Docs/commit/3d73cd3cbf7b5bf255982a14a8be760ffad68010

Thanks.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: function objects example

01 Dec 2019, 07:46

it was changed to work around the fact that obj.method() would also inject obj(hidden this) as the first parameter when calling the array, whereas %obj.method%() first retrieves the callable array and then calls it(the callable array) directly.
both of these used to work back when there was no method/property separation, but no longer do

here is the correct and more easily comprehensible version of this example:

Code: Select all

class FuncArrayType extends Array {
    Call(params*) {
	    ; Call a list of functions.
        for fn in this
        	%fn%(params*)
    }
}

; Define functions.
A(param1, param2) => MsgBox("Function 'A' called with '" param1 "' and '" param2 "'.")
B(param1, param2) => MsgBox("Function 'B' called with '" param1 "' and '" param2 "'.")
C(param1, param2) => MsgBox("Function 'C' called with '" param1 "' and '" param2 "'.")

; Create a callable array of functions, already populated with some (optional).
funcArray := FuncArrayType.New(Func("A"), Func("B"))

; Add more functions to the array after it has been created. (Can be done at any point.)
funcArray.Push(Func("C"))

; Create an object which uses the array as a method.
obj := {}

; Ignore the implicit hidden 'this'. Instead call the array and forward to it 
; all parameters that were passed to the method, when calling the method.  
obj.DefineMethod("method", (this, params*) => %funcArray%(params*))

; Call the method.
obj.method("foo", "bar")

also

Code: Select all

Loop Array.Length
	Array[A_Index]
for traversing sequentially is an antipattern. stop doing that
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: function objects example

01 Dec 2019, 12:01

That's a great example. Thanks.

(Just for the record, the example uses 'for traversing sequentially', I didn't post any code.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: function objects example

01 Dec 2019, 12:43

im aware of that. im just saying
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: function objects example

01 Dec 2019, 23:12

swagfag wrote:
01 Dec 2019, 07:46
also

Code: Select all

Loop Array.Length
	Array[A_Index]
for traversing sequentially is an antipattern. stop doing that
seems trivial to me.. i prefer the 'for' loop but why do you say the above is so bad?

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: function objects example

02 Dec 2019, 00:16

because it now does unnecessary bounds checking in addition to Array not having O(1) access(if that still hasnt been fixed already. i havent checked)
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: function objects example

07 Dec 2019, 19:32

Arr[A_Index] does not do bound-checking in v1, at least in any way that directly relates to A_Index. There are no such bounds to check, because Arr is an associative array. It just does key lookup, which is not O(1).

Arr[A_Index] does bound-checking in v2, assuming Arr is Array, because it is implemented as a true linear array, allowing O(1) access. To not do bound-checking would invite disaster, and be entirely inappropriate for a scripting language. (The point being that out-of-bounds access should have determinate behaviour, and that requires detecting out-of-bounds, i.e. performing bound-checking. How the array reacts to out-of-bounds access is a separate issue.)

Array enumerators in v2 also do bound-checking. How else would it know when to stop enumerating? The cost of evaluating the expression Array[A_Index] and the indexer property (__Item) on each iteration probably far exceeds the bound-checking. However, a for-loop needs to invoke the enumerator on each iteration, and that might be even slower (or still equally fast, depending on scale and perspective).

In v1, Loop might be used intentionally to ensure the inclusion of elements that have not been assigned values. In v2, such elements are enumerated by default (and are currently assumed to be blank, but can be detected with Has()).
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: function objects example

16 Jan 2020, 13:18

It was changed to fix the example which at the current time defined obj as, obj := {method: funcArray}, where method really is a property. The example was :arrow: later changed to properly define a method,

Code: Select all

obj := {}
obj.DefineMethod("method", funcArray)
But %obj.method%("foo", "bar") was erroneously kept, it should be obj.method("foo", "bar"), and the passing of parameters needs to be handled, either by modifying the functions to accept an additional parameter or by not passing the object.

Cheers.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: No registered users and 65 guests