ByRef Madness << Back



History: ByRef was introduced in VDF 11.0. It allows parameters to be passed "by reference" to a procedure/function. Combining with VDF's "Implicit Type Conversion", you've got some nasty bugs.

Use UI

Procedure StringByValue String sParam
	Move (sParam+"A") to sParam
End_Procedure

Procedure StringByRef String ByRef sParam
	Move (sParam+"A") to sParam
End_Procedure

String sString
Move "123" to sParam
Send StringByValue sParam // sParam will still be "123"
Send StringByRef (&sParam) // sParam will be "123A"

InKey FieldIndex

If a parameter is passed by value, regardless of what happens inside the subroutine, no changes will be applied to the caller's parameter. If a parameter is passed by reference, any changes you make to the parameter within the subroutine will be applied to the caller's parameter.

So far so good.

Use UI

Procedure StringByValue String sParam
	Move (sParam+"A") to sParam
	Showln sParam
End_Procedure

Send StringByValue 123 // Showln will show 123A
Send StringByValue (CurrentDateTime()) // Showln will show 6/12/2020 5:58:00.000 PMA

Procedure IntegerByValue Integer iParam
	Move (iParam + 2) to iParam
	Showln iParam
End_Procedure

Send IntegerByValue "1" // Showln will show 3
Send IntegerByValue (CurrentDateTime()) // ERROR here, see explanation below.

InKey FieldIndex

This is good-old VDF implicit type conversion. StringByValue is expecting a string. However you can totally call StringByValue with any data type that can be coerced (converted) into a string. The same concept applies to the procedure IntegerByValue. When you pass a data type that can not be coerced into the target data type (In this scenario, trying to convert a DateTime type into an Integer type), you will get the runtime error Illegal Datatype Conversion.

So far so good.

Here comes puzzle time!!

Use UI

Procedure AddCurrencySign String ByRef sVal
    Move ("$"+sVal) to sVal
End_Procedure

Procedure ShowStringWithCurrencySign String sVal
    Send AddCurrencySign (&sVal)
    Showln sVal // What will be shown???
End_Procedure

Number nNum
Move 12.22 to nNum
Send ShowStringWithCurrencySign nNum

InKey FieldIndex

What will be shown? Is it $12.22? The answer is $. But why? The procedures AddCurrencySign and ShowStringWithCurrencySign both look good. There is no syntax error or runtime error. What happened?

Use UI

Procedure TestByRef String ByRef s1 String ByRef s2
    Showln (s1+s2) // What will be shown???
End_Procedure

Procedure Test String s1 String s2
    Showln (s1+s2) // What will be shown???
    Send TestByRef (&s1) (&s2)
End_Procedure

Send Test 56 78

InKey FieldNumber

Here comes another similar puzzle - What will be shown? On Line 8, as you might have guessed - "5678". What about Line 4? You get a blank string.

Use WinShell.pkg

Procedure RemoveExt String sFile
    Integer iVoid
    Move (PathRemoveExtension(AddressOf(sFile))) to iVoid
End_Procedure

Procedure ByRefProc String ByRef sFile
    Showln "Before " sFile // Hello.txt
    Send RemoveExt sFile   // I am passing sFile by value into RemoveExt
    Showln "After " sFile  // Hello
End_Procedure

Procedure Main
    String sLocalFile
    Move "Hello.txt" to sLocalFile
    Send ByRefProc (&sLocalFile)
End_Procedure

Send Main
InKey FieldIndex

PathRemoveExtension is a Windows API call that removes the file extension from a file name. Here is another puzzle - sFile inside ByRefProc was changed by RemoveExt? But how?

Use UI

Procedure Method_C String ByRef sParam
    Move 'Voodoo' to sParam
End_Procedure

Procedure Method_B String sParam
    Send Method_C (&sParam)
End_Procedure

Procedure Method_A
    String sTest
    Send Method_B // Not passing any parameter!
    Showln "sTest: " sTest
    InKey FieldIndex
End_Procedure

Send Method_A

// sTest now contains the string "Voodoo"

I have no explanation for this one. That's just pure VDF voodoo.

Free Web Hosting