Is there an "Option Explicit" in PowerShell?

Option Explicit is well-known to VBScript programmers, as a means of enforcing best practices and - to be blunt - helping to prevent some common bugs. Essentially, Option Explicit requires that a variable be declared (such as by the Dim statement) prior to using the variable for any purpose. For better for for worse, PowerShell doesn't have anything exactly like it - although v2 does have something vaguely similar.

The Set-StrictMode cmdlet is capable of enabling a "strict mode" based on PowerShell versions. Run Set-StrictMode -version 2, and you'll find yourself in the current-maximum strictness level. In this level, you get an error when you attempt to access a variable that hasn't been initialized. This does NOT prevent you from accessing out-of-scope variables: If a variable doesn't exist in the local scope, PowerShell will still "climb the scope tree" to try and find it. For example, this works fine:

$x = 5
function foo { write $x }
foo

But this doesn't work, and generates an error:

function bar { write $y }
bar

Because $y hasn't been given a value in any scope when the function tries to access it.

v2 strict mode also prevents you from accessing non-existent properties of an object, something that v1 will handle easily (the property is just assumed to exist with a blank value). v2 strict mode will also bomb if you try to call a function using method syntax:

function zoom($a,$b) { write ($a+$b) }
zoom (5,1)

That function call is actually passing an array of two objects to parameter $a, leaving parameter $b empty. It's a mistake, something I still do a lot, because that's the syntax most programming languages use to call a function. The proper syntax in PowerShell would be:

zoom 5 1

Set-StrictMode isn't a perfect replacement for Option Explicit, and a lot of folks still wish we had something like Option Explicit. That'd take some work on Microsoft's park, because they'd also have to implement a formal means of declaring variables - something PowerShell actually lacks at present. But until (and if) that happens, Set-StrictMode can at least help prevent certain types of common, often typo-related bugs.

Discuss this Blog Entry 3

on Apr 14, 2011
Phil: You'll want to ask over at PowerGUI.org. They wrote those cmdlets and know a ton more about them than I do! But my guess is probably not without reprogramming the cmdlet.



on Apr 12, 2011
Hi Don,

I put this in my PS profile, as I was sick on mispelling my variables and having to debug my scripts. That was great for about 10 minutes....

as a result, my script for Exchange mailbox sizes stopped running due to a .count property which did not exist on a single user. I run $myUsers get-qaduser (scripts param) and I then check for $myUsers.count. if this is > 1 then I give the user a list of users return to select from. This now fails as a single user does not have a count property.

Are you aware of any way to ensure that a get-qaduser command ALWAYS returns collection and not a sinlge object ?

Thanks

Phil









on Apr 13, 2011
Hi Don,
the solution that might be offered is to declare every variable with its type like

for([int]$private:i = 0; $private:i -lt 10; $private:i++)
{
Write-Host $private:i;
for([int]$private:i2 = 0; $private:i2 -lt 10; $private:i2++)
{
Write-Host $private:i2;
}
}

but foreach, for example, does not support this way (it's a flaw compared to C#):
$env:Path.Split(";") | %{[String[]]$var = Get-ChildItem -Path $_}
foreach([string]$file in $var)
{Write-Host $file;}














Please or Register to post comments.

What's PowerShell with a Purpose Blog?

Don Jones demystifies Windows PowerShell.

Blog Archive

Sponsored Introduction Continue on to (or wait seconds) ×