objects: passing objects ByRef to a function Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

objects: passing objects ByRef to a function

29 Mar 2018, 04:43

- Parameters in functions can be defined as ByRef or not ByRef. If the parameter is not ByRef, any variables are cloned, and the original variable is left untouched. If the parameter is ByRef, any changes to the variable are permanent.
- Whether you pass an object as ByRef or not ByRef, any changes to the object are permanent. Does whether a parameter is ByRef or not have any effect on objects? Are there performance advantages/disadvantages, or other consequences?
- There is at least one difference that I know of, which is that if you pass an object ByRef, the reference count is not affected.

Code: Select all

q:: ;test object get reference count functions
obj := obj2 := obj3 := {}
MsgBox, % JEE_ObjRefCount(obj)
MsgBox, % JEE_ObjRefCountAlt(obj)
MsgBox, % ZJEE_ObjRefCount(obj)
MsgBox, % ZJEE_ObjRefCountAlt(obj)
return

;notice in the definitions whether 'ByRef' is used

JEE_ObjRefCount(ByRef oArray)
{
	;note: if you didn't use ByRef, this function itself would increase the ref count
	if !IsObject(oArray) ;it's a ptr
	{
		ObjAddRef(oArray)
		return ObjRelease(oArray)
	}
	ObjAddRef(&oArray)
	return ObjRelease(&oArray)
}

;==================================================

JEE_ObjRefCountAlt(ByRef oArray)
{
	;note: if you didn't use ByRef, this function itself would increase the ref count
	;note: this technique is undocumented, and may not work in future (tested on AHK v1.1)
	return NumGet(&oArray + A_PtrSize)
}

;==================================================

ZJEE_ObjRefCount(oArray)
{
	;note: if you didn't use ByRef, this function itself would increase the ref count
	if !IsObject(oArray) ;it's a ptr
	{
		ObjAddRef(oArray)
		return ObjRelease(oArray)
	}
	ObjAddRef(&oArray)
	return ObjRelease(&oArray)
}

;==================================================

ZJEE_ObjRefCountAlt(oArray)
{
	;note: if you didn't use ByRef, this function itself would increase the ref count
	;note: this technique is undocumented, and may not work in future (tested on AHK v1.1)
	return NumGet(&oArray + A_PtrSize)
}

;==================================================
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: objects: passing objects ByRef to a function  Topic is solved

29 Mar 2018, 09:08

If you pass a variable to a function in an "ByVal" parameter, the content of the variable will be copied to the function's local variable. The 'content' of an object variable is the object reference. If you copy that reference, it still points to the original object.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: passing objects ByRef to a function

29 Mar 2018, 13:03

- @just me: Thanks for bringing a bit of precision to this discussion.
- 'ByVal' is an interesting term that I'd come across before, I don't think it's mentioned in the documentation.
- A basic point just occurred to me, which is to consider what happens when var2 := var, and obj2 := obj are done (perhaps ByVal is equivalent), and ByRef would miss out this stage.
- Also, if you pass something like var1+var2 to a ByRef parameter, I suppose it has to this: arg := var1+var2 (ByVal), whereas if you pass var1 by itself, it doesn't have to do something like that (ByRef). (And you can check whether something was passed ByRef/ByVal by using IsByRef.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: passing objects ByRef to a function

31 Mar 2018, 19:16

There is another classic use of objects where ByRef is required. If you want to output an object ByRef that doesn't yet exist. I.e. to create an object rather than edit an object.

Code: Select all

q:: ;test create an object, return it ByRef
oArray := ""
MyByRefObjFunc(oArray)
MsgBox, % oArray.3 ;c
return

MyByRefObjFunc(ByRef oArray)
{
	oArray := ["a", "b", "c", "d", "e"]
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: objects: passing objects ByRef to a function

01 Apr 2018, 01:20

Obviously, you don't pass an object in this case. So it's not related to 'passing objects ByRef'.
User avatar
derz00
Posts: 497
Joined: 02 Feb 2016, 17:54
Location: Middle of the round cube
Contact:

Re: objects: passing objects ByRef to a function

01 Apr 2018, 16:26

jeeswg wrote:This is another classic use of objects where ByRef is required.
I'm not sure what you mean. Doesn't this function do the same thing, without ByRef?

Code: Select all

CreateObj()
MsgBox, % oArray.3 ; c

CreateObj() {
	global oArray := ["a","b","c","d","e"]
}
try it and see
...
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: passing objects ByRef to a function

02 Apr 2018, 16:56

- @derz00: In your function, there is only one object. In my function a new object is generated each time.
- Also, my function is good for local objects, your function creates a global object.
- Some code for testing.

Code: Select all

;test create an object
ObjOutByRef(oArray2)
ObjOutByRef(oArray3), oArray3.3 := "C"
ObjOutGlobal()
MsgBox, % oArray2.3 ;c
MsgBox, % oArray3.3 ;C
MsgBox, % oArray.3 ;c
MsgBox
TestObjOut()
return

TestObjOut()
{
	;global oArray
	ObjOutByRef(oArray2)
	ObjOutByRef(oArray3), oArray3.3 := "C"
	ObjOutGlobal()
	MsgBox, % oArray2.3 ;c
	MsgBox, % oArray3.3 ;C
	MsgBox, % oArray.3 ;(blank) ;this would not be blank if we uncomment the line 'global oArray'
}
ObjOutByRef(ByRef oArray)
{
	oArray := ["a", "b", "c", "d", "e"]
}
ObjOutGlobal()
{
	global oArray := ["a", "b", "c", "d", "e"]
}
- @just me: Well, there's 'passing objects *in* ByRef' and 'passing objects *out* ByRef', but yeah, I'd say the same as you if it was someone else's thread. These are the sorts of semantic discussions that can go on forever on the meta forums. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
derz00
Posts: 497
Joined: 02 Feb 2016, 17:54
Location: Middle of the round cube
Contact:

Re: objects: passing objects ByRef to a function

02 Apr 2018, 21:01

jeeswg wrote:- @derz00: In your function, there is only one object. In my function a new object is generated each time.
- Also, my function is good for local objects, your function creates a global object.
Alright, I see the difference. Either way, I don't see the purpose of this style of functions and creating arrays.
try it and see
...
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: objects: passing objects ByRef to a function

02 Apr 2018, 21:18

- Passing objects in ByRef, isn't that important:
- Whereas passing variables (string/integer/float) ByRef is useful so you can edit the variables, and avoid unnecessary data copying, with objects you can edit the arrays within the function whether they're ByRef or not.
- Passing objects out ByRef, is useful:
- You can create a new object and output it ByRef, useful if you want to save the return parameter for something else, e.g. I have a function which converts DllCall lines, and any errors are logged in an output array. You can also output multiple arrays this way.

Code: Select all

oArray := ""
MyObjOut1(oArray)
MsgBox, % oArray.2
oArray := ""
MyObjOut2(oArray)
MsgBox, % oArray.2

oArray := []
MyObjOut1(oArray)
MsgBox, % oArray.2
oArray := []
MyObjOut2(oArray)
MsgBox, % oArray.2

MyObjOut1(ByRef oArray)
{
	oArray := ["a", "b", "c"]
}
MyObjOut2(oArray)
{
	oArray := ["a", "b", "c"]
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: RandomBoy and 393 guests