úterý 14. října 2008

commonParameter -OutVariable

V předchozích dnech jsem připravoval prezentaci pro své kolegy (až bude hotová, tak ji vystavím i zde) a rozhodl jsem se použít skvělý skript Jeffreyho Snovera - Start-Demo. Jelikož jsem si nestáhl poslední verzi, narazil jsem na zajímavý "problém", který mě trošku zdržel, ale zároveň pomohl jít v PowerShellu opět trochu víc do hloubky. Jedná se o použití parametru OutVariable, který je jedním z takzvaných commonParameters.

Vyzkoušejte si následující dva příkazy (kdo neví, co je commonParameter, ať zkusí i ten třetí :)
$a = Get-ChildItem
Get-ChildItem -OutVariable b
Get-Help about_commonparameters

V proměnných $a i $b je stejný obsah a obě fungují správně jako objekty. Problém ale nastane při následujícím výpisu:

PS C:\> $a.Length
PS C:\> 28
PS C:\> $b.Length
PS C:\>

Druhý zápis nám nevydá nic :( Přitom obě proměnné mají stejný výstup Get-Member a oba drží jako své členy System.IO.FileInfo. Rozdíl je vidět z následujícího:

PS C:\> $a.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array

PS C:\> $b.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True ArrayList System.Object


První je Object[] a druhý ArrayList. Pokud bychom chtěli proměnnou $b převést na stejný typ jako $a, můžeme udělat následující:

$c = $b.ToArray()

Jelikož je $b zpracován uprostřed příkazů, chová se trochu jinak, než pokud je zpracován na konci (jako $a). Příklad, který naznačené velice hezky ukazuje si můžete vyzkoušet.

$i=0; Write-Output "3. Three","5. Five ","2. Two ","1. One ","4. Four " `
-outvariable unordered | sort `
| % { Write-Host "$_ " -fore green -NoNewLine; Write-Host $unordered[$i++] -fore Cyan }

Je vidět, že i když objekty setřídíme, tak proměnná $unordered stále obsahuje původní (nesetříděný) obsah pole.

Chtěl bych poděkovat Jaykulovi, který se mi na IRC trpělivě věnoval a osvětlil mi toto podivné chování a je také autorem uvedených vysvětlujících příkladů.

Žádné komentáře: