A paraméterek egyik nagyon érdekes fajtája a szkriptblokk . Enélkül csak nagyon nehézkesen, bonyolult programozással lehetne bizonyos feladatokat függvényekkel megoldani, szkripblokkokkal viszont nagyon egyszerűen. Nézzünk erre egy példát! Szeretnék egy általánosabb függvényt csinálni, az előző dupláz helyett, amellyel tetszőleges matematikai műveletet el tudok végezni a csővezetéken beérkező számokon. Ezt a műveletet paraméterként szeretném átadni a függvényemnek. Elsőre elég bonyolultnak tűnhet ilyesmit csinálni, de a szkriptblokkokkal pofonegyszerű:
[49] PS C:\>filter művelet ([scriptblock] $s)
>> {
>> &($s)
>> }
>>
[50] PS C:\>1,2,3 | művelet {$_*3}
3
6
9
[51] PS C:\>10,5,2 | művelet {$_/2}
5
2,5
1
A függvényem definíciója látható a [49]-es sorban. Egy „igazi” paramétere van, ami [scriptblock] típusú, a másik paramétere majd a csőből jön, és majd a $_ változón keresztül tudjuk megfogni. Maga a függvény törzse néhány karakter: „&($s)”, azaz csak annyi történik, hogy a paraméterként átadott szkriptet meghívjuk az „&” operátorral. És ezzel el is készült a nagy tudású, univerzális matematikai függvényünk! Persze a használatához tudni kell, hogy olyan kifejezést kell neki átadni paraméterként, ami a $_ változóval játszadozik, de amúgy tényleg egyszerű a dolog: az [50]-es sorban háromszoroz a függvényem, az [51]-es sorban pedig felez.
Valójában egy szkriptblokk nem csak paraméterként szerepelhet, hanem név nélküli függvényként is felfoghatjuk őket. Nézzük a legegyszerűbb csővezetékkel végezhető műveletet, adjuk vissza egyesével, változtatás nélkül a csőbe bemenő elemeket. Ugye megtanultuk, hogy a csőelemekhez a process szekcióban férünk hozzá a $_ változón keresztül. Első próbálkozás:
[85] PS C:\> 1, "kettő", 3.04 | process {$_}
Get-Process
: A positional parameter cannot be found that accepts argument '$_
'.
At line:1
char:27
+ 1,
"kettő", 3.04 | process <<<< {$_}
+ CategoryInfo : InvalidArgument: (:) [Get-Process],
ParameterBi
ndingException
+ FullyQualifiedErrorId :
PositionalParameterNotFound,Microsoft.PowerShel
l.Commands.GetProcessCommand
Ez nem jó, a csőjel (|) után valami kifejezést vár, valami végrehajtható dolgot, márpedig a process kulcsszó, nem végrehajtható kifejezés, ezért a PowerShell itt ezt úgy értelmezi, hogy az a Get-Process álneve, annak pedig nincs $_ paramétere. Segítsünk neki, csináljunk belőle szkriptet, pontosabban fogalmazva szkriptblokkot, amiben már van értelme a process kulcsszónak:
[86] PS C:\> 1, "kettő", 3.04 | {process {$_}}
Expressions
are only allowed as the first element of a pipeline.
At line:1
char:34
+ 1,
"kettő", 3.04 | {process {$_}} <<<<
+ CategoryInfo : ParserError: (:) [],
ParentContainsErrorRecordE
xception
+ FullyQualifiedErrorId :
ExpressionsMustBeFirstInPipeline
Ez sem lett sokkal jobb, merthogy – érdekes módon – a szkriptblokk sem végrehajtható! Az majdnem ugyanolyan adatszerűség, mint a változó, vagy akár egy szám. Segítsünk tovább neki, tegyünk elé egy végrehatás-operátort:
[87] PS C:\> 1, "kettő", 3.04 | &{process {$_}}
1
kettő
3,04
Na, itt már jól lefutott. Kis átalakítással ugyanazt a funkcionalitást el tudjuk érni, mint az előző alfejezet dupláz filteré:
[88] PS C:\> 1, "kettő", 3.04 | &{process {$_*2}}
2
kettőkettő
6,08
Azaz az ilyen szkriptblokkokat felfoghatjuk úgy is, mint anonim függvények. Ilyeneket akkor érdemes használni, ha nem akarom többször felhasználni a függvényt, hiszen akkor minek neki nevet adni?