Wednesday, February 17, 2016

Codependent simultaneous variable updates in PowerShell

I recently rediscovered the comma. There is always something more to learn in PowerShell. And not just the new big things. There are always little things that get missed or forgotten. I think I may have known about commas at one time, but did not find them of immediate use, so I forgot about them.

Specifically, I was reading an advance copy of chapter 1 of PowerShell in Action, Third Edition, by Bruce Payette and Richard Siddaway, and read that you can assign values to multiple variables at the same time in a single line by separating both the variable names and the values by commas.

So instead of this:

$A = 1
$B = 2

You can do this:

$A, $B = 1, 2

Most of the time, you would never do that. The first syntax is much more clear.

But there are two situations where this is useful. One is when a command naturally results in the multiple values you are looking to assign.

Instead of this:

$FQDN = "Server1.HQ.contoso.com"
$FQDNArray = $FQDN.Split( ".", 3 )
$ComputerName = $FQDNArray[0]
$ChildDomain = $FQDNArray[1]
$RootDomain = $FQDN[2]

You can do this:

$FQDN = "Server1.HQ.contoso.com"
$ComputerName, $ChildDomain, $RootDomain = $FQDN.Split( ".", 3 )

Where it becomes really useful, is when you have to make simultaneous codependent changes to your values.

For example, if you need to swap two values, instead of this

$Temp = $A
$A = $B
$B = $A

You can do this:

$A, $B = $B, $A

Or let’s say you are working on a script for calculating Mandelbrot’s set. You will have a function that sets complex number Z to Z squared plus C. As a complex number, Z has both a real component and an imaginary component. In your calculation, you need to use the old value of the real component to calculate the new value of the imaginary component, and you need the old value of the imaginary component to calculate the new value of the real component.

Instead of this:

$Newr = $Zr * $Zr - $Zi * $Zi + $Cr
$Newi = 2 * $Zr * $Zi + $Ci
$Zr = $Newr
$Zi = $Newi

You can do this:

$Zr, $Zi = ( $Zr * $Zr - $Zi * $Zi + $Cr ), ( 2 * $Zr * $Zi + $Ci )

(And yes, I know there are .Net object that will let you work with complex numbers even more easily than that, but this is the conceit of the example, so deal with it.)