Name of key that stores reference to object vs name of t obj

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Name of key that stores reference to object vs name of t obj

17 Oct 2013, 10:58

I have a dumb question.

Lets suppose I have an object named obj. Obj has the key named 2. The value of the key is: a reference (a pointer) to another object. The question is: is the name 2 the name of the _key_ or the name of the _object_ (the object the key named 2 references to)?

The only reference the compiler has to the 'another object' object is inside of the value of the key named 2.

If the name 2 is the name of the key (whatever that means), does that mean that I can have an object _with no name_ and that object may still exist because some key stores a reference to that object? (~can I have an object with no name from the point of view of the compiler)


The background of this question is to understand how multidimensional arrays work; in particular, how is an expression such as: tab[1][2][3] (which contains names / operators / temporary objects (references to objects?) ) translated to chunks of memory (to C like structures) that create a logical structure that is a 3D table. I've noticed that, when a 3D table is created in Autohotkey, then, besides objects that contain 'pure values of the table', there are other objects that only contain references to other objects. Through those objects that are sort of the meta-elements of the table, the structure of the table (the dimensions) is created.
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Name of key that stores reference to object vs name of t

17 Oct 2013, 11:54

The question is: is the name 2 the name of the _key_ or the name of the _object_ (the object the key named 2 references to)?
"2" is just the name of the key
If the name 2 is the name of the key (whatever that means), does that mean that I can have an object _with no name_ and that object may still exist because some key stores a reference to that object? (~can I have an object with no name from the point of view of the compiler)
Yes, e.g.:

Code: Select all

obj := {2: {base:{__Delete:"Del"}}}
MsgBox, % IsObject(obj[2])
obj[2] := "" ; Release object with no 'name'
return

Del(obj)  {
	MsgBox, % "Object with no 'name' at address: '" &obj "' released."
}
lexikos
Posts: 9688
Joined: 30 Sep 2013, 04:07
Contact:

Re: Name of key that stores reference to object vs name of t

17 Oct 2013, 17:17

As far as the program is concerned, 2 is just a number.

It is only a "name" because you perceive it as such. Objects don't have names in reality, only in your imagination. obj is also not the name of an object; it is the name of a variable containing an object.

Humans often assign many names to a thing - you can call the object whatever you want.
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Name of key that stores reference to object vs name of t

18 Oct 2013, 02:52

Coco: thanks; so the object whose reference is stored inside of the value of the key named '2' 'has no name' and yet I can operate on that object by sort of using _the address_ of that object.
lexikos wrote:obj is also not the name of an object; it is the name of a variable containing [a reference to] an object.
Lexikos: thanks; the way I was thinking about names of objects / variables was like this: when the compiler reads the text file of the script which (the file) is to-be-converted to the binary code, the compiler has to create a list of all variables used inside of the script. To uniquely reference a particular variable, humans use 'names'. Because humans use 'names', humans _use_ those names inside of the script's text file. So the compiler has to store _the name_ of the variable somewhere, even if the compiler _internally_ remembers the unique variable by remembering _the address_ of that variable inside of the memory (if the compiler does it this way). The way I was imagining 'a name' attached to [a variable that contains] an object was sort of an additional chunk of data that floats above the variable, like a balloon. I now realized that the 'name' (vs the address) can't be the unique map, because of namespaces.

So I guess what I really wanted to know was, how does the compiler uniquely identify the particular binary instance of the object whose _name_ was used inside of the txt file of the script? The compiler has to have some map that matches a given 'name' of the object to the address of that object in the memory.

What I was also confused about is: is _the key_ [of an object] a variable? I ask because HotkeyIt recently showed me that in addition to storing a reference to an object inside of the value of the key, I can also store a reference to the object inside of _the name?_ of the key?
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Name of key that stores reference to object vs name of t

18 Oct 2013, 03:21

What I was also confused about is: is _the key_ [of an object] a variable? I ask because HotkeyIt recently showed me that in addition to storing a reference to an object inside of the value of the key, I can also store a reference to the object inside of _the name?_ of the key?
I assume what you mean is:
obj := {"key": []} ; store object as value of "key"
obj := {[]:"Some string"} ; Use object as key with value "Some string"
In the second example:
If you don't have a reference to the object(stored it in a variable), your best bet to retrieve whatever value it holds is to do a for-loop

Code: Select all

obj := {"key": [], []: "Hello World"}
for k, v in obj {
	if IsObject(k)
		MsgBox, % "Object used as key.`nObject address: " &k "`nThe value is = '" v "'."
	else if IsObject(v)
		MsgBox, % "Object assigned as value to key.`nObject address: " &v "`nThe key is = '" k "'."
}
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Name of key that stores reference to object vs name of t

18 Oct 2013, 03:48

Coco, yes, this is exactly what I was after. I realized that it is possible to place references to objects in _both_ the _key_ and the value (sort of as they really were 'the key _variable_' and 'the value _variable_'). This lead me to testing that even if I don't have the 'name' of the key (bc i.e. that key contains a reference to an object), then it is still possible to reference to the _value_ of that key through the for loop (actually, I should say: the for loop retrieves the value of 'the 'key' variable'?). The conclusion was that inside of one key-value pair of the object, it is possible to store _two_ references to objects, thus 'saving space'.

Another conclusion was that 'properties' of keys and values inside of an object are 'symmetric' (or 'equivalent') - _both_ the key and the value can store _any_ value. Whereas previously I was thinking that the key can only store _subsets_ of values: either strings or numbers (~non-object values?) and the 'value' can store _any_ value.
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Name of key that stores reference to object vs name of t

18 Oct 2013, 04:15

Here is way to retrieve object reference w/o storing a copy in a variable:

Code: Select all

oKey := []
oAddress := &oKey ; Store object address, NOTE: This does not increment object reference count 
obj := {(oKey):"Hello World"} ; increments object reference count
oKey := "" ; release reference, decrements object reference count
MsgBox, % obj[Object(oAddress)] ; get object reference by passing object address to Object() function
return
lexikos
Posts: 9688
Joined: 30 Sep 2013, 04:07
Contact:

Re: Name of key that stores reference to object vs name of t

18 Oct 2013, 17:46

trismarck wrote:So I guess what I really wanted to know was, how does the compiler uniquely identify the particular binary instance of the object whose _name_ was used inside of the txt file of the script?
I think your question is flawed. As I said, objects don't have names. Also, objects don't exist in the text file of the script; only instructions to create and manipulate objects, store them in variables or other objects, etc.

The "compiler" doesn't identify objects. Compilation is what happens before the script runs.

Each piece of data must exist somewhere. Objects, variables, strings, etc. all exist in memory. Only one thing can be at any given position in memory, so objects are identified by their address in memory. That is, a reference to an object is the object's address coupled with the knowledge that we're identifying an object (since obviously other things exist in memory).
The [program] has to have some map that matches a given 'name' of the object to the address of that object in the memory.
No it doesn't, because objects don't have names. For x := Object(), "x" is the name of a variable. For x.y := Object(), "x" is the name of a variable and "y" is a key (a string stored in an object and associated with some other value). You could say that "x" and "y" are names of objects, but it is all in your head; the program maps the name "x" to a variable and uses the string "y" to find the second object within the first object.
What I was also confused about is: is _the key_ [of an object] a variable?
In the general sense, a variable is something that is liable to vary or change. A key cannot change; it's just a value, like "xyz" or 42. You can store a key-value pair in an object, modify the value or remove the key-value pair, but you cannot change the key, therefore it is not a variable.

In a computing sense, a variable is a container for a value. Again, a key is a value, like "xyz" or 42. You can store one or many keys in an object, and each one can be a string, number or object reference. So you could say that an object is a variable, or that there is a variable for each key and value inside the object.

However, for AutoHotkey, "variable" has a narrower meaning: x and y in x := y are variables. An object is not a "variable" and does not contain "variables"; an object is an associative array. A key is just a value used with an object in a specific manner.
... I can also store a reference to the object inside of _the name?_ of the key?
You must be confused, since you wrote a statement but put a question mark at the end. I'd say the object is a key, or is used as a key. You don't name or put something inside a key, you just use it to unlock something.
the for loop retrieves the value of 'the 'key' variable'?
The for-loop retrieves the key, as it says in the documentation. ;)
_both_ the key and the value can store _any_ value.
Nope.
Keys can be strings, integers or objects, while values can be of any type.
Source: Objects
AutoHotkey 32-bit supports integer keys in the range -2147483648 to 2147483647. AutoHotkey supports 64-bit integers, but only AutoHotkey 64-bit supports the full range [of integers] as keys in an object.
...
Floating-point numbers are not supported as keys - instead they are converted to strings.
Source: Objects
Coco wrote:Here is way to retrieve object reference w/o storing a copy in a variable:
What was the purpose of your example? &Object and Object(ptr) should not be used lightly (i.e. without first learning how reference counting works). Storing the address is essentially the same as storing a reference, except that it interferes with reference counting. Instead of "storing a copy in a variable", you store the address in a variable. Either way you use a variable, so I don't see the point.
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Name of key that stores reference to object vs name of t

19 Oct 2013, 00:30

&object and Object(ptr) is useful in cases where one would need to do circular references:

Code: Select all

class A
{
	
	static __instances__ := []

	__New(name) {
		A.__instances__[name] := &this ; store address
		this.name := name
	}

	__Delete() {
		MsgBox, % "Instance of class 'A' released"
		A.__instances__.Remove(this.name) ; remove address
	}
}

class B
{
	
	static __instances__ := []

	__New(name) {
		B.__instances__[name] := this ; store reference
		this.name := name
	}

	__Delete() {
		MsgBox, % "Instance of class 'B' released"
		B.__instances__.Remove(this.name)
	}
}

x := new A("NameToIdentifyX")
MsgBox, % (x == Object(A.__instances__["NameToIdentifyX"]))

y := new B("NameToIdentifyY")
MsgBox, % (y == B.__instances__["NameToIdentifyY"])

x := "" ; This calls A.__Delete()

y := "" ; Does not call B.__Delete() because of circular reference

/*
;to release 'y' one must explicitly do:
B.__instances__.Remove(y.name)
*/
return
I agree one should know how reference counting works though. As for trismarck's case, he wants to use an object as 'key', he could access the 'value' by either doing a for-loop, storing a reference to the object in a variable, or storing the address of the object in a variable.
lexikos
Posts: 9688
Joined: 30 Sep 2013, 04:07
Contact:

Re: Name of key that stores reference to object vs name of t

19 Oct 2013, 19:27

Coco wrote:&object and Object(ptr) is useful in cases where one would need to do circular references:
Right. This new example has a reason to use &object. The other one doesn't.
As for trismarck's case, he wants to use an object as 'key', he could access the 'value' by [...] storing the address of the object in a variable.
What I'm saying is that there's no good reason to do that, but good reasons not to. So why demonstrate it that way without demonstrating the simpler, safer way and/or explaining the drawbacks?

Actually, &object is perfectly safe if you just use it as a unique identifier and never do Object(address).
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Name of key that stores reference to object vs name of t

23 Oct 2013, 10:03

:D
Coco wrote:

Code: Select all

class A
{
	
	static __instances__ := []
...
So __Delete is called _not_ if I assign an empty value to the variable that originally held the object: y := "", but rather only when _the last reference_ to the object is released. Actually, the object is deleted when _the reference count_ of the object equals 0, regardless of how many 'references' there currently are in the script.
Coco wrote: I agree one should know how reference counting works though. As for trismarck's case, he wants to use an object as 'key', he could access the 'value' by either doing a for-loop, storing a reference to the object in a variable, or storing the address of the object in a variable.
No, the only reason I asked about a key that stores a reference to the object was to understand this syntax: obj.fun[obj]() (thought that maybe there should be "obj" instead of obj). But thanks Coco for 'expanding my knowledge' :lol:

Also, to clarify, the circular reference in this context is: multiple references to the same [binary] object vs a circular reference which occurs if i.e. we have two objects: x and y, we store references to those objects in variables a and b and a key of object x points to object y and key of object y points to object x.
lexikos wrote:
Coco wrote:&object and Object(ptr) is useful in cases where one would need to do circular references:
Right. This new example has a reason to use &object. The other one doesn't.
As for trismarck's case, he wants to use an object as 'key', he could access the 'value' by [...] storing the address of the object in a variable.
What I'm saying is that there's no good reason to do that, but good reasons not to. So why demonstrate it that way without demonstrating the simpler, safer way and/or explaining the drawbacks?

Actually, &object is perfectly safe if you just use it as a unique identifier and never do Object(address).
Hmm, so the drawback of storing an address as the unique identifier of the object (or actually, to retrieve the address of the object through the & operator) is that at some point I may pass that address to a function through DllCall, and that function will release the object under the address w/o informing AHK about the wipe-out. Or, I may forget to later on decrement the reference count (I shouldn't decrement when I'm using &, I should do that only when I'm using Object(obj) - this gets tricky).
Another thing is that doing _both_ Object(address) or Object(object) increments the reference count for the object and thus may create a memory leak. Before analyzing the responses I've thought that Object(object) would _decrement_ the reference count and Object(address) would increment the reference count, but this apparently is not the case.
Also, even by doing x == Object(address) (store and quickly delete the temporary object) I also increment the reference count for the object.

Code: Select all

class cx {
	__Delete() {
		MsgBox __Delete()
	}
}

obj := new cx()
MsgBox, % ObjAddRef(&obj)*0 + ObjRelease(&obj) ; 1
Address := Object(obj)
MsgBox, % ObjAddRef(&obj)*0 + ObjRelease(&obj) ; 2
	; => Object(object) _increases_ the reference count
b := Object(Address)
MsgBox, % ObjAddRef(&obj)*0 + ObjRelease(&obj) ; 3
	; Object(address) _also_ increases the reference count
	;

Code: Select all

Loop, 100
	a := Object({})
MsgBox, % IsObject(a) ; 0
MsgBox, % ObjAddRef(a)*0 + ObjRelease(a) ; 1 

Code: Select all

obj := {}
Loop, 100
	a := Object(obj)
MsgBox, % ObjAddRef(a)*0 + ObjRelease(a)	; 101
Thanks.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], peter_ahk and 133 guests