Inconsistent behavior of deref in closure Topic is solved

Discuss the future of the AutoHotkey language
User avatar
aseiot
Posts: 13
Joined: 05 Mar 2017, 04:25

Inconsistent behavior of deref in closure

12 May 2018, 10:04

I find %VAR% is not work consistently in closures.

Code: Select all

F(){
	X := 100
	Y := "X"

	TEST_DEREF(){
		MsgBox %Y% ; suppose to 100, actually empty
	}

	TEST_DEREF()

}

F()
If we do some operation before deref, it work as expected.

Code: Select all

F(){
	X := 100
	Y := "X"

	TEST_DEREF(){
		ANYTHING := X ; do any operation before deref
		MsgBox %Y%	; 100 as expected.
	}

	TEST_DEREF()

}

F()
Helgef
Posts: 3531
Joined: 17 Jul 2016, 01:02
Contact:

Re: Inconsistent behavior of deref in closure  Topic is solved

12 May 2018, 10:22

This behaviour is documented and works a expected,
Nested functions wrote:Dynamic variable references inside a nested function can resolve to variables from the outer function only if the nested function (or one of its own nested functions) also contains a non-dynamic reference to the variable.
If we do some operation before deref, it work as expected.
The sufficient operation is referring to the variable, non-dynamically. (X) alone is enough, and need not be executed ,eg,

Code: Select all

TEST_DEREF(){
	MsgBox %Y% ; 100
	return
	(X)
}
Cheers.

Edit: english
Last edited by Helgef on 21 May 2018, 01:06, edited 1 time in total.
User avatar
aseiot
Posts: 13
Joined: 05 Mar 2017, 04:25

Re: Inconsistent behavior of deref in closure

12 May 2018, 11:32

Thanks for explanation! Cheers.
lexikos
Posts: 6207
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Inconsistent behavior of deref in closure

12 May 2018, 17:49

The set of "free variables" available to closures is intentionally restricted (based on what references can be discovered at load time) so that the function can be allowed to clear its other local variables when it returns. Aside from generally being conservative, this avoids creating circular references in some cases, such as:
  • when the function stores a reference to a closure in a local variable,
  • when the function stores a reference to a closure in an object referred by a local variable, such as this in a method,
... but doesn't refer to that variable within any closures.

A circular reference would prevent the closure, all associated free variables, all objects referred by those variables and so on, from being freed until the circle is broken. Breaking a circular reference is harder for closures than for objects because the variables are not accessible from outside.

Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 3 guests