Csővezeték feldolgozása (Foreach-Object) – újra

Ugyan már volt szó a ForEach-Object  cmdletről a 1.5.5 ForEach-Object cmdlet fejezetben, de most már ismerjük a függvényeket és filtereket, így tisztában vagyunk azzal, hogy hogyan történik a csővezetéken érkező objektumok feldolgozása paraméterként átadott szkriptblokkok segítségével.

Tulajdonképpen már mi magunk is meg tudnánk írni egy ForEach-Object cmdlethez hasonló működésű függvényt, de mivel ezt olyan gyakran használnánk, hogy érdemesebb volt ez gyorsabban lefutó, natív PowerShell parancsként implementálni.

Ennek ellenére elég tanulságos lenne egy ilyen függvényt írni. Ehhez először nézzük meg a ForEach-Object szintaxisát:

[1] PS C:\> (get-help foreach-object).syntax

 

ForEach-Object [-process] <ScriptBlock[]> [-inputObject <psobject>] [-begin

 <scriptblock>] [-end <scriptblock>] [<CommonParameters>]

Most a CommonParameters részt kihagyom, de a többit én is definiálom a függvényemben:

function saját-foreachobject ([scriptblock] $process = $(throw "Kötelező!"),

     [PSObject] $inputObject, [scriptblock] $begin, [scriptblock] $end)

{

     begin

     {

       if($inputObject)

       {

          $inputObject | saját-foreachobject -p $process -b $begin -e $end

          return

       }

       if($begin) {&$begin}

     }

     process {&$process}

     end

     {

         if($end) {&$end}

     }

 }

Itt a $process paraméter kötelezően kitöltendő, hibát ad a függvényem, ha ez hiányzik:

[3] PS C:\> 222 | saját-foreachobject

Kötelező!

At line:1 char:63

+ function saját-foreachobject ([scriptblock] $process = $(throw <<<<  "Kötele

ző!"),

    + CategoryInfo          : OperationStopped: (Kötelező!:String) [], Runtim

   eException

    + FullyQualifiedErrorId : Kötelező!

Ha ez helyesen van kitöltve, akkor akár csővezetékkel is jól működik:

[4] PS C:\> 1,3,44, "q" | saját-foreachobject {$_*3}

3

9

132

qqq

De működik úgy is, ha nem „belecsövezzük” a feldolgozandó objektumot, hanem ‑inputobject paraméterként átadjuk:

[5] PS C:\> saját-foreachobject {$_*2} -i 654

1308

Ehhez a függvénydefinícióban egy kicsit trükköztem, ha ez utóbbi módszerrel akarnék objektumot átadni, akkor nem lenne $_ változó, ezért a begin szekcióban meghívom rekurzív módon a függvényből saját magát, immár csövezős módszerrel. Azért, hogy a rekurzív hívásból visszatérve ne fusson le még egyszer a függvényem, ezért ott egy return-nel kilépek.

Ilyen jellegű csövezhető paraméterátadást a PowerShell 2.0 fejlett függvényeivel sokkal egyszerűbben és profibban meg tudunk valósítani, ott nem kell rekurzív hívást külön leprogramozni. (Ld. 2.5 Fejlett függvények – script cmdletek fejezet!)

Megjegyzés

Vizsgáljuk meg egy kicsit jobban ezt a futószalag-rendszert! Nézzük a következő példát, ahol a bemeneti elemeket ráteszem a futószalagra, majd 3 foreach-object „gépen” is keresztülmegy a nyersanyag:

PS C:\> 'a', 'b', 'c' |

>>     ForEach-Object -Begin {Write-Host "Az 1. gép beindul"} -Process {"$_ 1"}

 -End {write-host "Az 1. gép leáll"} |

>>     ForEach-Object -Begin {Write-Host "Az 2. gép beindul"} -Process {"$_ 2"}

 -End {write-host "Az 2. gép leáll"} |

>>     ForEach-Object -Begin {Write-Host "Az 3. gép beindul"} -Process {"$_ 3"}

 -End {write-host "Az 3. gép leáll"}

>> 

Az 1. gép beindul

Az 2. gép beindul

Az 3. gép beindul

a 1 2 3

b 1 2 3

c 1 2 3

Az 1. gép leáll

Az 2. gép leáll

Az 3. gép leáll

A kimenetből látható, hogy az egymás utáni szakaszok gépeinek begin szekciói szépen egymás után lefutnak, mint ahogy az elinduló futószalag is minden gép előtt elindul. Ezután az egyes elemek, ahogy végig haladnak a gépek előtt, úgy dolgoznak rajtuk a gépek, először az első, majd második, végül a harmadik. A futószalag leállása megint mindhárom gépet egyszerre érinti.



Word To HTML Converter