Friday, August 14, 2009

Bug in PowerShell?

Yesterday I wrote about a way how to use [HashTable] type as single storage for different values… Well, code has to be changed a bit.

Remember that you can access member by using $People.$Foo? But it doesn’t work always, so you should use $People.[string]$Foo instead.

Have a look at following code:

[hashtable]$Collection = @{}
For ($i = 0; $i -lt 10; $i += 1) {$Collection.$i = $i}



Looks fine, doesn’t it? Well, let’s have a look at keys:



PS C:\> $Collection.Keys
9
8
7
6
5
4
3
2
1
0



Still ok. Now try to retrieve value for one of the keys:



PS C:\> $Collection.9
Unexpected token '.9' in expression or statement.
At line:1 char:14
+ $Collection.9 <<<<
+ CategoryInfo : ParserError: (.9:String) [], ParentContainsError
RecordException
+ FullyQualifiedErrorId : UnexpectedToken



Hmmmmmm, error. Let’s have a look at key type:



PS C:\> $Collection.Keys | ForEach {$_.GetType()}

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



Have you noticed something? Key should be always string, however in this case, PowerShell doesn’t convert it automatically. Surprisingly, this allows us to have 2 keys with same name – something that should never happen ;)



PS C:\> $Collection."9" = 9
PS C:\> $Collection.Keys
9
9
8



Ok, and here comes solution. Whenever you assign key, specify that it is string:



[hashtable]$Collection = @{}
For ($i = 0; $i -lt 10; $i += 1) {$Collection.[string]$i = $i}

No comments: