Name of an Array in a function call - possible to know?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Name of an Array in a function call - possible to know?

21 Jan 2018, 15:55

An little example!
I have a function with name GetArrValue(ArrayName, Key) like this!

Code: Select all

Color := {Blue: "0x0000FF", Yellow:"0xFFFF00"}
MsgBox % " Color .: " Color.Yellow

ArrName := "Color"
ArrKey := "Yellow"
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % GetArrValue(ArrName, ArrKey)
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % GetArrValue("Color", "Green")

GetArrValue(ArrayName, Key)
{	If !IsObject(ArrayName)
	{	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, The Array .: %ArrayName% does not exist. `nThis program is ended!
		ExitApp
	}
	If !%ArrayName%.HasKey(Key)
	{	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, The Key .: %Key% does not exist in the Array .: %ArrayName% `nThis program is ended!
		ExitApp
	}
	Return % %ArrayName%[Key . ""]
}
It works! but if the "ArrName" outside the function doesn't exist, and a call to the function with that "Array name", I don't get the name of the wrong "Array name" in the function. Is it possible to show the "Array name" in the function?

i.e. If a call to the function, with an array thats not exist, like this .:

Code: Select all

Result := GetArrValue("AllColor","Blue")
This message appears .: "The Array .: does not exist..."
My wish is to get this message.: "The Array .: AllColor does not exist..."
Is it possible?
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Name of an Array in a function call - possible to know?

22 Jan 2018, 12:01

Running your code snippet results in
MagBox wrote:---------------------------
Row.: 11 -> F5668071.ahk
---------------------------
The Array .: Color does not exist.
This program is ended!
---------------------------
OK
---------------------------
here. I've tested with 1.1.25.02 and 1.1.27.07.

Code: Select all

If !IsObject(ArrayName)
will never be true if you pass the array name as a string. A variable containing a string is not an object. You'll find the solution 4 lines down.
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Re: Name of an Array in a function call - possible to know?

22 Jan 2018, 17:35

Many thanks (again!)
The following code is the result.:

Code: Select all

#SingleInstance Force
#NoEnv

Color := { Blue:"0x0000FF", Yellow:"0xFFFF00" }

ArrName := "Color"
ArrKey := "Yellow"
If IsObject(%ArrName%)
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "The Array .: " ArrName " exist."

HexColor := GetArrValue(ArrName, ArrKey)
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % HexColor

GetArrValue(ArrayName, Key)
{	If !IsObject(%ArrayName%)
	{	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "The Array .: " ArrayName " does not exist. `nThis program is ended!"
		ExitApp
	}
	If !%ArrayName%.HasKey(Key)
	{	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "The Key .: " Key " does not exist in the Array .: " ArrayName " `nThis program is ended!"
		ExitApp
	}
	Return % %ArrayName%[Key . ""]
}
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Re: Name of an Array in a function call - possible to know?

23 Jan 2018, 07:09

As I see it, a variable must be created with the object name, for later information about the name of the object.

i.e. This work, because the variable "ArrName" contain the Array name

Code: Select all

Color := { Blue:"0x0000FF", Yellow:"0xFFFF00" }
ArrName = Color
If IsObject(%ArrName%)
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "The Array .: " ArrName " exist."
This can never work - because it's impossible to get the name on the Array itself

Code: Select all

Color := { Blue:"0x0000FF", Yellow:"0xFFFF00" }
If IsObject(Color)
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "The Array .: " Color " exist."
Is that correct?
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Re: Name of an Array in a function call - possible to know?

23 Jan 2018, 08:32

Hmmm.
Here is an example that creates an Array with Arrays as keys.

Code: Select all

ResultArray := CreateArray()
ResultV = ResultArray
ShowArray(ResultV)
ExitApp

CreateArray()
{	Array_X1 := { ArtNo:"101264", Head1:"Info1b", Count:4, Supplier:"Supp2" }
	Array_X2 := { ArtNo:"939431", Head1:"Info1c", Count:17, Supplier:"Supp" }
	
	ProdInfo := { "101264":Array_X1, "939431":Array_X2 }

	Return ProdInfo
}	

ShowArray(ArrayName)
{	For i, Value in %ArrayName%
	{	List .= "Loop .: " A_Index "`tKey . .: " i "`nValue . . . . . . . . . . .: " Value "`n`n"
		KeyCount += 1
	}
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%,
	(LTrim Join 
		%  "Name .: " ArrayName "`n
		Number of Keys .: " %ArrayName%.Length() "pcs. `n
		Number of Keys .: " KeyCount "pcs.`n
		- - - - - - - - - - - - - -`n
		Show the keys .: `n`n
	" List
	)
}
Is it then impossible to display the contents of the keys in the array (because the keys are arrays and it's impossible to get the name of the arrays)?
Is there any solution to this?
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Name of an Array in a function call - possible to know?

23 Jan 2018, 10:44

You are creating a two-dimensional array/object. That means, the 'value' of each 'key' of the first dimension contains an array/object reference. Your function is equivalent with

Code: Select all

CreateArray()
{	
	ProdInfo := { "101264": { ArtNo:"101264", Head1:"Info1b", Count:4, Supplier:"Supp2" }, "939431": { ArtNo:"939431", Head1:"Info1c", Count:17, Supplier:"Supp" } }
	Return ProdInfo
}
In this case the name of the key is also the name of the array reference in its value. You can get access the values of the second dimension using

Code: Select all

ResultArray[FirstDimensionKey, SecondDimensionKey]
How to 'show' a two-dimensional array:

Code: Select all

ResultArray := CreateArray()
ResultV := "ResultArray"
Show2DArray(ResultV)
ExitApp

CreateArray()
{
	Array_X1 := { ArtNo:"101264", Head1:"Info1b", Count:4, Supplier:"Supp2" }
	Array_X2 := { ArtNo:"939431", Head1:"Info1c", Count:17, Supplier:"Supp" }

	ProdInfo := { "101264":Array_X1, "939431":Array_X2 }

	Return ProdInfo
}

Show2DArray(ArrayName) ; for a two-dimensional array
{
	For Key1, KeyArray in %ArrayName%
	{
		List .= "Loop .: " A_Index "`tKey .: " Key1 . "`n"
		KeyCount += 1
		For Key2, Value In KeyArray
		{
			List .= "`tLoop .: " A_Index "`tKey .: " Key2 "`tValue .: " Value "`n"
		}
		List .= "`n"
	}
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%,
	(LTrim Join
		%  "Name .: " ArrayName "`n
		Number of Keys .: " %ArrayName%.Length() "pcs. `n
		Number of Keys .: " KeyCount "pcs.`n
		- - - - - - - - - - - - - -`n
		Show the keys .: `n`n
	" List
	)
}
And again, if your script will create arrays from variables, don't use literal assignments like Array_X1 := { ArtNo:"101264", Head1:"Info1b", Count:4, Supplier:"Supp2" } to test it. The results might differ.
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Re: Name of an Array in a function call - possible to know?

23 Jan 2018, 11:33

just me wrote:......And again, if your script will create arrays from variables, don't use literal assignments like Array_X1 := { ArtNo:"101264", Head1:"Info1b", Count:4, Supplier:"Supp2" } to test it. The results might differ.
What do you mean?

I can understand why Number of Keys .: %ArrayName%.Length() doesn't work.
But have no idea why Number of Keys .: " KeyArray.Length() "pcs. dosen't work for me.
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Name of an Array in a function call - possible to know?

23 Jan 2018, 11:51

I mean integer vs. string keys.
Albireo wrote:But have no idea why Number of Keys .: " KeyArray.Length() "pcs. dosen't work for me.
KeyArray.Length() should be used only for 'simple arrays' and returns "the highest positive integer key contained by the object, or 0 if there aren't any". KeyArray contains only string keys because of the literal string assignments. (We're running in circles :crazy:)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Name of an Array in a function call - possible to know?

23 Jan 2018, 12:17

Here's an object pointer to object variable name example.
object pointer to object variable name - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=43238
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Re: Name of an Array in a function call - possible to know?

23 Jan 2018, 19:46

jeeswg wrote:Here's an object pointer to object variable name example.
object pointer to object variable name - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=43238
I will watch on it tomorrow (thank you)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
I have a function ShowArray(Array, A_LineNumber)
The idea is that the function should be able to display the contents of an Array, both if the call contains a variable with the array name or the array itself.

Code: Select all

#SingleInstance Force
#NoEnv

Color := { Blue:"0x0000FF", Yellow:"0xFFFF00" }

ShowArray(Color, A_LineNumber)
ShowArray("Color", A_LineNumber)
ExitApp

ShowArray(ArrayName, JumpFromLine)
{	; Version .: 24 jan 2018
	; Handles both calls of Object and Variables
	; - e.g. Call with a variable .: ShowArray("Color", A_LineNumber)
	; - e.g. Call with an Object.: ShowArray(Color, A_LineNumber)
	; The program continues even if "ArrayName" is NOT an array.
	; Displays both "KEY" and "Value" - e.g. [ArtNo: 1]
	; At the bottom of MsgBox, is a summary displayed.

		
	If StrLen(ArrayName)
	{	ObjectName = %ArrayName%
		ObjName = %ArrayName%
	}
	else
	{	ObjectName = Unknown
		ObjectText = (The ArrayName is not a variable)
		ObjName = ArrayName
	}

	If !IsObject( %ObjName% )	; Is not an Array
	{	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%,
		(LTrim Join
		%	"Array .: ( " ObjName " ) does not exist! `n`n
			The program continues!"
		)
		Return
	
	}
	
	For i, Value in %ObjName%	; For "Key", "Value" i SimpleArray - Get the key!
	{	List .= "Loop .: " A_Index "`tKey . .: " i "`nValue . . . . . . . . . . . . . . . . .: " Value . "" "`n`n"		
		KeyCount = %A_Index%
	}
	
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%,
	(LTrim Join 
		% List "`n
		Function .: ShowArray `n
		Table .: " ObjectName "  " ObjectText "`n
		Call from Line .: " JumpFromLine "`n
		Number of keys .: " KeyCount " pcs.`n`n"
	)
}
The function does what I desired, but if the Array is big, what happens with the computer memory?

If I understand correctly, the Array will be doubled in this operation .:

Code: Select all

	If StrLen(ArrayName)
	{	ObjectName = %ArrayName%
		ObjName = %ArrayName%
	}
	else
	{	ObjectName = Unknown
		ObjectText = (The ArrayName is not a variable)
		ObjName = ArrayName
	}
Will the computer's memory be freed when the function ends?

Is it better to make two different loops? like this .: (not tested!)

Code: Select all

If StrLen(ArrayName)
{	For i, Value in %ArrayName%
	{	List .= "Loop .: " A_Index "`tKey . .: " i "`nValue .: " Value . "" "`n`n"		
		KeyCount = %A_Index%
	}
}
else
{	For i, Value in ArrayName
	{	List .= "Loop .: " A_Index "`tKey . .: " i "`nValue .: " Value . "" "`n`n"		
		KeyCount = %A_Index%
	}
}
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Name of an Array in a function call - possible to know?

24 Jan 2018, 04:26

If I understand correctly, the Array will be doubled in this operation .:
What should 'double the array'? You're assigning a string in the Ifas well as in the Else branch.
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Re: Name of an Array in a function call - possible to know?

29 Jan 2018, 05:40

Has no idea how Autohotkey stores variables. (That's why I think about this)
If I have an associative array, such as this .:

Code: Select all

TestArray := {ten: 10, twenty: 20, thirty: 30}
The values is stored in the computer memory. I have no idea how much memory this array needs, but maybe 10-20 bytes.
If I copy TestArray like this .:

Code: Select all

TestArray1 := TestArray
must even the TestArray1 occupy 10-20bytes from the computer memory. (Is that correct?)

And if the array %Arrayname% has 50,000 keys and the value is strings, it takes a lot of memory from the computer in my question.

Code: Select all

	If StrLen(ArrayName)
	{	ObjectName = %ArrayName%
		ObjName = %ArrayName%
	}
	else
	{	ObjectName = Unknown
		ObjectText = (The ArrayName is not a variable)
		ObjName = ArrayName
	}
I think the array ObjectName occupies as much memory as the array ArrayName above, after the copy? (Am I wrong?)
What happens to all arrays / variables that are not Global in a function in AHK?
Are these deleted and computer memory freed after the AHK-function is done?
or is it better to empty large arrays before the function ends?
Is there a risk of memory leaks? (memory not released when the AHK program ends)
I wondered how to best manage my function "ShowArray"
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Name of an Array in a function call - possible to know?

30 Jan 2018, 03:32

Object variables don't contain the object itself. They contain a "reference", i.e. a pointer to the object's structure in memory. So

Code: Select all

TestArray1 := TestArray
won't "duplicate" the object's memory. It just stores a second reference to the object defined by TestArray in TestArray1.

And again, all assignments are strings, not objects.

Code: Select all

	If StrLen(ArrayName) ; ensures that Arrayname contains a string, not an object
	{	ObjectName = %ArrayName% ; copies the string contained in Arrayname to ObjectName
		ObjName = %ArrayName%  ; copies the string contained in Arrayname to ObjName
	}
	else
	{	ObjectName = Unknown ; assigns a literal string
		ObjectText = (The ArrayName is not a variable)  ; assigns a literal string
		ObjName = ArrayName ; assigns the literal string "ArrayName"
	}
Albireo
Posts: 1748
Joined: 16 Oct 2013, 13:53

Re: Name of an Array in a function call - possible to know?

30 Jan 2018, 11:49

just me wrote:Object variables don't contain the object itself. They contain a "reference", i.e. a pointer to the object's structure in memory. ...
Maybe it could be like that, but what happen if the values is changed in the object TestArray1?

Code: Select all

TestArray1 := TestArray
Is it still the same reference in memory? I do not think it may be so - or...?
(I see no difference between TestArray1 := TestArray and TestArray1 = %TestArray%)
just me wrote:...all assignments are strings, not objects...
I may not really understand what is meant.

TestArray := {ten: 10, twenty: 20, thirty: 30} is not that an object with KEYs and values?
or is that only a string like this .: {ten: 10, twenty: 20, thirty: 30} nothing more?

I am still thinking about the other questions...
What happens to all arrays / variables that are not Global in a function in AHK? (or strings?)
Are these deleted and computer memory freed after the AHK-function is done?
or is it better to empty large arrays before the function ends?
Is there a risk of memory leaks?
(memory not released when the AHK program ends)

The idea of the AHK-function ShowArray is to easily see what a specific associative array contains.
If the call to ShowArray, contains an object or variable, you can get a result in both cases.
(But the object's name remains unknown in the function, if the call to ShowArray contains an object).
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Name of an Array in a function call - possible to know?

30 Jan 2018, 16:55

Albireo wrote:Maybe it could be like that, but what happen if the values is changed in the object TestArray1?
Why don't you test it?

Sorry, I give up.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], ntepa and 244 guests