Concepts and Conventions | AutoHotkey
https://www.autohotkey.com/docs/Concepts.htm#caching
The situation is quite different and far simpler in AHK v2:In effect, a variable can contain both a string and a number simultaneously. Usually this just improves the script's performance with no down-sides, but if a variable contains both a number and a string, is it number, or is it a string?
Concepts and Conventions | AutoHotkey v2
https://lexikos.github.io/v2/docs/Concepts.htm#caching
In the collection below, I try to summarise the key things to be aware of. I also list some techniques and queries. Please notify of any issues, and do suggest any additions. Cheers.
Code: Select all
;caching examples and queries (AHK v1)
;==================================================
oDict := ComObjCreate("Scripting.Dictionary")
oDict.Item["0x1"] := "string: 0x1"
oDict.Item["1"] := "string: 1"
oDict.Item[1] := "number: 1"
;==================================================
vNum := "0x1" ;cache: string
MsgBox, % oDict.Item[vNum] ;string: 0x1
;a numeric comparison is required, so a numeric cache is needed:
vTemp := (1 = vNum) ;cache: string and number
;Concepts and Conventions | AutoHotkey
;https://www.autohotkey.com/docs/Concepts.htm#caching
;Objects don't have the capability to store both a number and a string as a key or value.
;Since numbers are more memory-efficient, if a variable has both, the number is used (except for floating-point values used as keys).
vNum := [vNum].1 ;cache: number
;Concepts and Conventions | AutoHotkey
;https://www.autohotkey.com/docs/Concepts.htm#caching
;In order to pass parameters to a COM object, the program must convert the variable's content to either a number or a string.
;...
;If a variable has both, the number is used.
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
vNum := "0x1" ;cache: string
MsgBox, % oDict.Item[vNum] ;string: 0x1
;a numeric comparison is required, so a numeric cache is needed:
vTemp := (1 = vNum) ;cache: string and number
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
vNum := "0x1" ;cache: string
MsgBox, % oDict.Item[vNum] ;string: 0x1
;a numeric comparison is required, so a numeric cache is needed:
if vNum
(0) ;NoOp ;cache: string and number
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
vNum := 0x1 ;cache: number and string (unintuitive)
MsgBox, % vNum ;0x1
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
vNum := 0x1+0 ;cache: number
MsgBox, % vNum ;1
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
vNum := 01 ;cache: string and number (unintuitive)
MsgBox, % vNum ;01
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
;queries: 'vNum := 1' has a numeric cache, but does it have a string cache?
vNum := 1 ;cache: string and number (unintuitive) [CHECK][does it have a string cache?]
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
vNum := 1+0 ;cache: number
MsgBox, % oDict.Item[vNum] ;number: 1
;Concepts and Conventions | AutoHotkey
;https://www.autohotkey.com/docs/Concepts.htm#caching
;Taking the address of a variable effectively converts the variable's value to a string
;Variables and Expressions - Definition & Usage | AutoHotkey
;https://www.autohotkey.com/docs/Variables.htm#unary
;&MyVar also disables the caching of binary numbers in that variable
vTemp := &vNum ;cache: string
MsgBox, % oDict.Item[vNum] ;string: 1
;==================================================
;queries: when using 'if', does it check the numeric cache or string cache first (if one check succeeds, does it skip the other check) (i.e. does it do short-circuit Boolean evaluation)
;queries: does 'if var' on cache (number), add a string cache?
;'if var' on cache (string), adds a numeric cache:
vNum := "0x1" ;cache: string
if vNum
(0) ;NoOp
MsgBox, % oDict.Item[vNum] ;number: 1
;inconclusive: does 'if var' on cache (number), add a string cache?
vNum := 1+0 ;cache: number
if vNum
(0) ;NoOp
MsgBox, % oDict.Item[vNum] ;number: 1
;==================================================
;queries: how to check if an item has a string cache (MsgBox can sometimes reveal this)
;==================================================
;queries: how to get the address of the numeric cache (you can't?)
;==================================================
;queries: why does VarSetCapacity on var1 give 6
;var1 := 0
;var2 := 1
;var3 := 0+0
;var4 := 1+0
;MsgBox, % VarSetCapacity(notavar) ;0
;MsgBox, % VarSetCapacity(var1) ;6
;MsgBox, % VarSetCapacity(var2) ;0
;MsgBox, % VarSetCapacity(var3) ;0
;MsgBox, % VarSetCapacity(var4) ;0
;==================================================
Links:
if statement influences floating point number - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=14&t=53498
Object.Push is eating initial zeros - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=64932
If statement changes contents of var - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=14&t=70330