Static initializers do not initialize anything Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
hachi
Posts: 15
Joined: 16 Jan 2017, 19:29

Static initializers do not initialize anything

13 Sep 2018, 00:14

This method seems straightforward in the docs, but does not work at all as expected

Code: Select all

get_oauth() {
	static oauth := 0
	if !oauth {
		fo := FileOpen(a_scriptdir "\oauth", 0)
		oauth := fo ? fo.read() : 0
	}
	return oauth
}
I want to read this file only once, not every time the function is called. Warn always complains that oauth is undefined, why?
Rohwedder
Posts: 7612
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Static initializers do not initialize anything

13 Sep 2018, 03:29

Hallo,
I have tested this:

Code: Select all

#warn
Loop
	MsgBox, % get_oauth()
get_oauth() {
	static oauth := 0
	if !oauth {
		fo := FileOpen(a_scriptdir "\oauth", 0)
		oauth := fo ? fo.read() : 0
		ToolTip, % A_TickCount
	}
	return oauth
}
No complains that oauth is undefined.
If a non-empty textfile oauth exists, it will only be read once.
hachi
Posts: 15
Joined: 16 Jan 2017, 19:29

Re: Static initializers do not initialize anything

16 Sep 2018, 14:59

I should be more specific it only happens during init, the function is in standard lib and this warning appears every time I reload a calling script. If I set a listvars/tooltip in the function just where you have the tickcount, it shows this value being stored as expected, and returns later without falling into this block as it should... just not when the script first loads it.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Static initializers do not initialize anything  Topic is solved

16 Sep 2018, 22:20

If you are calling the function (directly or indirectly) from a static initialiser, check the order of the static initialisers in your script.
hachi
Posts: 15
Joined: 16 Jan 2017, 19:29

Re: Static initializers do not initialize anything

18 Sep 2018, 05:41

lexikos wrote:If you are calling the function (directly or indirectly) from a static initialiser, check the order of the static initialisers in your script.
Duh thank you... did not occur to me this order would matter. Also the warn dialog is kind of vague in this context,

Code: Select all

; read oauth from file
lib_oauth() {
	static oauth := 0
	if !oauth
		; read oauth
	return oauth
}

; requires authentication + clientID
lib_REST_command() {
	static oauth := lib_oauth(), clientID := lib_clientID()
	; send command
	return response
}
	
; also requires authentication
lib_clientID() {
	static oauth := lib_oauth(), clientID := 0
	if !clientID
		; get clientID
	return clientID
}
In this order, warn always points to the var oauth in lib_clientID, when it's apparently the var clientID in lib_REST_command() which produces the warning. If I load lib_clientID before that, no problem.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Static initializers do not initialize anything

18 Sep 2018, 17:16

In this order, warn always points to the var oauth in lib_clientID,
When I run the excerpt you posted, it warns about clientID.

The warning dialog points at the line that was executing when the uninitialized variable was accessed, and is usually correct. It prints the name of the uninitialized variable which is being read - this is always accurate. In this case, you call lib_clientID() from a static initializer which precedes lib_clientID(), therefore clientID won't be initialized when lib_clientID() is first called, and it will display a warning for this before the ; get clientID code executes. After that it might print other warnings, if the comment is replaced with code.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Static initializers do not initialize anything

18 Sep 2018, 21:00

Why not use a class for this?
hachi
Posts: 15
Joined: 16 Jan 2017, 19:29

Re: Static initializers do not initialize anything

20 Sep 2018, 15:53

lexikos wrote:When I run the excerpt you posted, it warns about clientID.
I explained it wrong, not the initializing var being pointed at but a later evaluation which fails -

Code: Select all

; read oauth from file
lib_oauth() {
	static oauth := 0
	if !oauth
		; read oauth
	return oauth
}

; requires authentication + clientID
lib_REST_command() {
	static oauth := lib_oauth(), clientID := lib_clientID()
	; send command
	return response
}
	
; also requires authentication
lib_clientID() {
	static oauth := lib_oauth(), clientID := 0
	
	if !oauth	; <-- warn points to this line/reference, oauth undefined
		return "error"
	if !clientID
		; get clientID
	return clientID
}
kczx3 wrote:Why not use a class for this?
more than one interface depends on this token/client, I want these functions to be callable elsewhere for now.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], haomingchen1998, mikeyww and 236 guests