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.
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?
returnByRef(A,B,C)
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%, % A "," B "," C
returnByRef(ByRef val1, ByRef val2, ByRef val3)
{
val1 := "A"
val2 := 100
val3 := 1.1
return
}
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.
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
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 ""
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.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance Force
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
; Test aVar4 - Works (inside and outside the function)
; Note .: The array name is not the same, (inside and outside the function)
Line := A_LineNumber + 2
Info = - Test of aVar4 (Row .: %Line% )`nfuncByRef(Line, Info, aVar4)
aVar := funcByRef(Line, Info,aVar4)
Gosub Result
MsgBox ,,, Ready!, 2
ExitApp
Result:
if isobject(aVar4)
Info1 = It works!
else
Info1 = It doesn't work!
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
% "Result OUTSIDE the function()
" Info "`n
aVar4[2] .: " aVar4[2] " - " Info1 "
aVar[1] .: " aVar[1]
)
Return
funcByRef(FromRow, Info, ByRef Var4 := "")
{
funcName = funcByRef()
; Var2 = From inside %FuncName%
Var3 := Var3 * 10
aVar := {}
aVar.Push("Test1")
aVar.Push("Test2")
Var4 := aVar
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
% " - INSIDE .: " funcName "
" Info "`n
Var4[2] .: " Var4[2] "
aVar[1] .: " aVar[1]
)
Return % aVar
}
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.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance Force
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
; Test aVar4 - Works (inside and outside the function)
; Note .: The array name is not the same, (inside and outside the function)
Line := A_LineNumber + 2
Info = - Test of aVar4 (Row .: %Line% )`nfuncByRef(Line, Info,,,,,aVar4)
aVar := funcByRef(Line, Info,,,,aVar4)
Gosub Result
; Test Var3a - Maybe works - I got nothing as result (inside and outside the function)
Line := A_LineNumber + 2
Info = Test of Var3a `nfuncByRef(Line, Info,,,Var3 ,aVar4)
aVar := funcByRef(Line, Info,,,Var3 ,aVar4)
Gosub Result
; Test Var3b - Works (inside and outside the function) - I got 1000 as expected
Line := A_LineNumber + 3
Info = Test of Var3 `nfuncByRef(Line, Info,,,Var3 ,aVar4)
Var3 = 100
aVar := funcByRef(Line, Info,,,Var3 ,aVar4)
Gosub Result
; Test Var3c - Don't work (The result in the function is 10 and outside the function is 100)
Line := A_LineNumber + 3
Info = Test of Var3 `nfuncByRef(Line, Info,,,Var3 ,aVar4)
Var3 = 1
aVar := funcByRef(Line, Info,,,,aVar4)
Gosub Result
MsgBox ,,, Ready!, 2
ExitApp
Result:
if isobject(aVar4)
Info1 = It works!
else
Info1 = It doesn't work!
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
% "Result OUTSIDE the function()
" Info "`n
Var1 .: " Var1 "
Var2 .: " Var2 "
Var3 .: " Var3 "
aVar4[2] .: " aVar4[2] " - " Info1 "
aVar[1] .: " aVar[1]
)
Return
funcByRef(FromRow, Info, Var1 := "Only local", ByRef Var2 := "Default Value" , ByRef Var3 := "10", ByRef Var4 := "")
{
funcName = funcByRef()
; Var2 = From inside %FuncName%
Var3 := Var3 * 10
aVar := {}
aVar.Push("Test1")
aVar.Push("Test2")
Var4 := aVar
MsgBox ,, Row.: %A_LineNumber% -> %A_ScriptName%,
( LTrim
% " - INSIDE .: " funcName "
" Info "`n
Var1 .: " Var1 "
Var2 .: " Var2 "
Var3 .: " Var3 "
Var4[2] .: " Var4[2] "
aVar[1] .: " aVar[1]
)
Return % aVar
}
My conclusion .: Using ByRef and setting a Default value seems difficult/ impossible to manage at the same time.
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.
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.