ByRef - Nothing happens Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
Albireo
Posts: 1231
Joined: 16 Oct 2013, 13:53

ByRef - Nothing happens

27 Jul 2019, 09:24

I tried to return an array and three variables from a function.
To succeed with this, I intended to use ByRef
All of these variables are normally empty before the function is used,
Thought to provide a default value for these variables with ByRef.

I wrote this test program to show my wishes .:

Code: Select all

funcByRef()
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
 %	"`tResult test 1 `n
	Var1 .: " Var1 "
	Var2 .: " Var2 "
	Var3 .: " Var3 "
	aVar[1] .: " aVar[1]
)

Var3 = 100
funcByRef(,,Var3)
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
 %	"`tResult test 2 `n
	Var1 .: " Var1 "
	Var2 .: " Var2 "
	Var3 .: " Var3 "
	aVar[1] .: " aVar[1]
)




ExitApp


funcByRef(Var1 := "Def", ByRef Var2 := "" , ByRef Var3 = 10)
{	Var2 = inside the function
	Var3 := Var3 * 10
	
	aVar := {}
	aVar.Push("Test1")
	aVar.Push("Test2")
	
	MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
	( LTrim
	 %	"    Inside the function() `n
		Var1 .: " Var1 "
		Var2 .: " Var2 "
		Var3 .: " Var3 "
		aVar[1] .: " aVar[1]
	)
	Return % aVar
}
Something I've misunderstood with ByRef?

Also tried ByRef aVar := {} but it didn't AHK like at all ;)
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: ByRef - Nothing happens

27 Jul 2019, 10:04

I tried to return an array and three variables from a function.
You succeeded in returning an array from the function, but in your test there is no catcher.
To catch the "rebouncing" return value, you write:

Code: Select all

aVar := funcByRef()
Albireo
Posts: 1231
Joined: 16 Oct 2013, 13:53

Re: ByRef - Nothing happens

27 Jul 2019, 14:56

comments from wolf_II
Of course! (I forgot it) - Thanks!
First I tried (as I said) to also include the array with ByRef like this .:

Code: Select all

funcByRef(Var1 := "Def", ByRef Var2 := "" , ByRef Var3 = 10, ByRef aVar := {})
But I got an error message.... I gave up to use ByRef with the array aVar
Var2 never gets any value from FuncByRef().
After the second case Var3 seems to work as desired. (after the first case I got nothing...)
What am I doing wrong?

In the helpfile for ByRef it was an example .:
ByRef from AHK helpfile
It's almost the same as mine example, but they don't have any default value.
In the help file it says .: (exactly what I want)
Since return can send back only one value to a function's caller, ByRef can be used to send back extra results. This is achieved by having the caller pass in a variable (usually empty) in which the function stores a value.
Under ByRef / optional parameters the helpfile says .:
ByRef parameters also support default values; for example: MyFunc(ByRef p1 = ""). Whenever the caller omits such a parameter, the function creates a local variable to contain the default value; in other words, the function behaves as though the keyword "ByRef" is absent.
Have I understood correctly, What I am trying to do will not work (is impossible in AHK)?
A little updated test program, also with examples from the AHK help file
Is this possible to solve in another way?
hd0202
Posts: 163
Joined: 04 Oct 2013, 03:07
Location: Germany near Cologne

Re: ByRef - Nothing happens  Topic is solved

28 Jul 2019, 02:11

1) you did not mark the relevant part of the help text:
ByRef parameters also support default values; for example: MyFunc(ByRef p1 = ""). Whenever the caller omits such a parameter, the function creates a local variable to contain the default value; in other words, the function behaves as though the keyword "ByRef" is absent..
This means: you must give a parameter to the function for each value you want returned "Byref"

2) you cannot give an array as default value, so you got an error message. use instead ""

Code: Select all

funcByRef(Var1 := "Def", ByRef Var2 = "" , ByRef Var3 := "10", Byref Var4 := "")
3) MsgBox does not show the content of an object automatically, so you must check for it

Code: Select all

If isobject(var...)
I connect my version of your last test code:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
funcByRef(, Var2, , Var4)
if isobject(var4)
	MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
	( LTrim
	 %	"`tResult test 1 with object in var4, but without catcher`n
		Var1 .: " Var1 "
		Var2 .: " Var2 "
		Var3 .: " Var3 "
		Var4 .: is object
		aVar[1] .: " aVar[1]
	)

aVar := funcByRef(, Var2, , Var4)
if isobject(var4)
	MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
	( LTrim
	 %	"`tResult test 1 with object in var4`n
		Var1 .: " Var1 "
		Var2 .: " Var2 "
		Var3 .: " Var3 "
		Var4 .: is object
		aVar[1] .: " aVar[1]
	)

MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
 %	"`tResult test 1 `n
	Var1 .: " Var1 "
	Var2 .: " Var2 "
	Var3 .: " Var3 "
	Var4 .: " Var4 "
	aVar[1] .: " aVar[1]
)

Var1 =
Var2 = 
Var3 = 100

aVar := funcByRef(, Var2, Var3)
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
 %	"`tResult test 2 `n
	Var1 .: " Var1 "
	Var2 .: " Var2 "
	Var3 .: " Var3 "
	aVar[1] .: " aVar[1]
)


ReturnByRef(A,B,C)
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%, % "AHK -example ByRef .: `n`n"A "," B "," C


ExitApp

ReturnByRef(ByRef val1, ByRef val2, ByRef val3)
{
    val1 := "A"
    val2 := 100
    val3 := 1.1
    Return
}


funcByRef(Var1 := "Def", ByRef Var2 = "" , ByRef Var3 := "10", Byref Var4 := "")
{	Var2 = inside the function
	Var3 := Var3 * 10
	
	aVar := {}
	aVar.Push("Test1")
	aVar.Push("Test2")
	var4 := avar
	
	MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
	( LTrim
	 %	"    Inside the function() `n
		Var1 .: " Var1 "
		Var2 .: " Var2 "
		Var3 .: " Var3 "
		Var4 .: " Var4 "
		aVar[1] .: " aVar[1]
	)
	Return % aVar
}
Hubert
Albireo
Posts: 1231
Joined: 16 Oct 2013, 13:53

Re: ByRef - Nothing happens

28 Jul 2019, 06:23

Thanks!
Now it works to send an array from a function using ByRef ;)
The question remains .: How to use a default value at the same time you want to use ByRef

But… (only look on the "Array" Var4 / aVar4)
Whats the difference by this two functions? .:
  • funcByRef(FromRow, Info, ByRef Var4 := "")
  • funcByRef(FromRow, Info, ByRef Var4)
I can (as I see it) never give a default value in this case.
Give a value to a variable that will later be converted to an array, it felt pointless.
TestScript Var4 / aVar4



We can look at three examples of handling .: Var3 - The function .:
funcByRef(FromRow, Info, Var1 := "Only local", ByRef Var2 := "Default Value" , ByRef Var3 := "10", ByRef Var4 := "")

a) Var3 has no value before funcByRef(Line, Info,,,Var3 ,aVar4)
It works? inside and outside the function (do not use the default value) - I got nothing as result.

b) Var3 is set before the function call like this.
Var3 = 100
aVar := funcByRef(Line, Info,,,Var3 ,aVar4)

Yes! ByRef works, but does not use the default value.

c) Var3 is not in the function call, like this .:
aVar := funcByRef(Line, Info,,,,aVar4)
Yes/No! default value works (in the function), but does not return some result to the main program.
AHK -test Var3 ByRef / DefaultValue


My conclusion .: Using ByRef and setting a Default value seems difficult/ impossible to manage at the same time.
  • ByRef - can never be skipped (as I understand it)
  • Variables with default values - can be skipped.
swagfag
Posts: 3972
Joined: 11 Jan 2017, 17:59

Re: ByRef - Nothing happens

28 Jul 2019, 08:26

Code: Select all

; Test Var3c - Don't work (The result in the function is 10 and outside the function is 100) 
wrong. inside the function Var3 is 100, and outside of it it is 1

to have a byref be optional and default initializable when passed an unitialized variable u have to do this:

Code: Select all

f(ByRef x := "") {
	if (x = "")
		x := "default"
}
Albireo
Posts: 1231
Joined: 16 Oct 2013, 13:53

Re: ByRef - Nothing happens

28 Jul 2019, 18:21

If you use the following If-sequence in the function

Code: Select all

if (x = "")
   x := "default"
I still don't see the big difference between the following different ByRef to the function f()
1) f(ByRef x := "") (in the example from @swagfag )
2) f(ByRef x = "") (from the AHK-helpfile for ByRef )
3) f(ByRef x) (No default value at all)
All three examples give the same result from the function f()
What I want to highlight is that the default value together with ByRef does not work.
just me
Posts: 7224
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ByRef - Nothing happens

29 Jul 2019, 07:28

1) f(ByRef x := "") The expressional := assignment operator was introduced with AHK 1.1.09.
2) f(ByRef x = "") The = does the same.
3) f(ByRef x) The parameter x is mandatory here. Try to call the function as Result := f().

Default values are only used with optional parameters if you do not pass a variable or a value.

Return to “Ask For Help”

Who is online

Users browsing this forum: AHKStudent, aifritz, Bing [Bot], Google [Bot], Jugi and 37 guests