PMP Style .global

PMP Style .global

Software engineer page

MENU

Pass multiple arguments to a function by reference

PowerShell is a quirky language, and it's often confusing because it has a slightly different grammar. It's also hard to use arguments passed by reference in a function.
In a new language, you get stuck in such a basic place.

Step 1

Adding ref to a reference is the same concept as C # etc. If you call like this

Function fnc([int]$x, [int]$y, [ref][int]$w, [ref][int]$z)
{
    if($y -ne 0) {
        $w = $x / $y
        $z = $x * $y
        Return $true
    } else {
        Return $false
    }
}

[int]$z = 0
[int]$w = 0
[Boolean]$ret = fnc 10 5 [ref]$w [ref]$z
$ret
$w
$z

Result

fnc: Unable to handle argument conversion for parameter'w'. Unable to convert value "[ref] 0" to type "System.Int32". Error: "The format of the input string is incorrect." 
Location C:\temp\test.ps1: 19 Characters: 26 
+ [Boolean]$ret = fnc 10 5 [ref]$w [ref]$z
+                          ~~~~~~~
    + CategoryInfo          : InvalidData: (:) [fnc]、ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,fnc

There seems to be a problem with how to call it.

Step 2

Rule 1: Enclose in parentheses when passing arguments by reference Example: ([ref]$w)

Note that instead of fnc (10, 5, [ref] $ w, [ref] $ z), fnc 10 5 ([ref] $ w) ([ref] $ z) and each argument in parentheses It is to tie up. Also note that the argument delimiters are spaces, not commas. It feels strange that the function definition uses commas but should not be used when calling, but I have to get used to it.

Let's run it.

Function fnc([int]$x, [int]$y, [ref][int]$w, [ref][int]$z)
{
    if($y -ne 0) {
        $w = $x / $y
        $z = $x * $y
        Return $true
    } else {
        Return $false
    }
}

[int]$z = 0
[int]$w = 0
[Boolean]$ret = fnc 10 5 ([ref]$w) ([ref]$z)
$ret
$w
$z

Result

True
0
0

Well, there is no value even though it does not cause an error. I should be referring to it.
When I first encountered it, I gave up using it for mysterious specifications.
If you stumble in such a place, you will lose your motivation.

Step 3

Rule 2: Use the Value property when setting a value for a referenced argument. example: $w.Value = 10

Mystery is. There is a feeling of strangeness. [ref] [int] $w, so even though it is an int type, is there a Value property?
There is it. Looking up the type information with $w.GetType () ...

$w.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                                                       
-------- -------- ----                                     --------                                                                                                                                                       
True     True     Int32                                    System.ValueType    

It's an object like this. And there is a property called Value. Now let's get back on track and try the following:

Function fnc([int]$x, [int]$y, [ref][int]$w, [ref][int]$z)
{
    if($y -ne 0) {
        $w.Value = $x / $y
        $z.Value = $x * $y
        Return $true
    } else {
        Return $false
    }
}

[int]$z = 0
[int]$w = 0

[Boolean]$ret = fnc 10 5 ([ref]$w) ([ref]$z)

$ret
$w
$z

Result

True
2
50

It finally worked. You can understand it by trying it with a sample.