Summary: Microsoft Scripting Guy, Ed Wilson, talks about working with fixed number sizes in Windows PowerShell.
Hey, Scripting Guy! I have a script that returns a specific type of number, so I added a type constraint on the variable that holds the number. The problem is that sometimes when I run the script, I get errors. I cannot figure this out. Can you help me?
—BG
Hello BG,
Microsoft Scripting Guy, Ed Wilson, is here. We have not had any snow this year here in Charlotte, North Carolina. This is good news, and of course, bad news. The good news is that because the city is rarely prepared for snow storms, any snow at all causes major problems. The bad news is that we do not get to see snow very often—maybe once every three or four years, if we are lucky. Personally, I enjoy looking at snow from the windows, but I really do not like it when I have to get outside in it. Snow causes lots of problems if you are not expecting it, and if you are not prepared for it.
We run into much the same issue when it comes to constraining number types in Windows PowerShell. Because Windows PowerShell has a greatly enhanced adaptive-type system, and it can change the types of the objects that lay under the covers, one rarely needs to deal with things (such as a type mismatch) that plague other object-oriented languages.
This, of course, has good and bad effects. At times, if I am not really paying attention, I can get tripped up if I am not expecting the object transformation. To be honest, this has only happened to me a couple of times, and it was usually because I was trying to do something pretty tricky in the first place. One way around this, is to place a type constraint on the object, and then force it to raise an error message when the change takes place. This can be helpful for spotting these sorts of changes.
Note To be clear, most of the time (in fact, I would say over 90 percent of the time), it is best to allow Windows PowerShell to manage the types.
Changing number types
The default number type in Windows PowerShell is an Int, and that is also an Int32. If the number becomes too big, Windows PowerShell will change the number from an Int to a Double. I wrote the following script to illustrate the point:
function get-double
{
Param($a)
$b = $b + $a
"now $($b.gettype())"
if ($b -eq 'Infinity') {Return}
get-double $b
}
I load the function and call it by passing the number 2. This is shown here:
Get-Double 2
When I run the script, it runs for a few seconds and then stops when it reaches Infinity. Part of the output is shown here:
It is clear from the output that when Windows PowerShell reaches the maximum value of Int32, it changes the type of number that is contained inside the variable $b to a Double. Most of the time, this is the behavior I want.
Constraining the type of the number in a variable
But suppose that the value of $b should never become greater than a certain value, and that number is an Int. The script appears to work, but it takes a long time to complete. As I troubleshoot the script, I decide to constrain the value of $b to a number type that makes sense for my script. I'm going to try an Int16.
In the following script, I use the type constraint [int16] to ensure that the variable $b only holds an Int16.
function get-int
{
Param($a)
$erroractionpreference = "stop"
[int16]$b = $b + $a
"now $b"
get-int $b
}
If the value in $b becomes greater than 32768, an error arises. Because the error that arises is not a terminating error, the script would run and run and run, but continue to display errors. That is not the behavior I want, so I changed the value of $errorActionPreference from "continue" to "stop". The output is shown here:
By constraining the type of number that I store in the $b variable, it becomes obvious that the problem with my script is that I am, somehow, getting a number that is too big. In reality, a problem such as that is usually traceable to one of the following:
- A loop that runs too long (an upper limit is not properly controlling the loop execution)
- Variables that are not being properly initialized prior to reuse
Because Windows PowerShell has an adaptive-type system, such problems are often difficult to see. They show themselves as weird and inconsistent output, or you may have a script that appears to work, but it takes a really long time to complete. Constraining my types can make troubleshooting easier and enable me to more readily spot such problems.
BG, that is all there is to using numeric type constraints. Numbers Week will continue tomorrow when I will talk about more cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy