Ne használjon globális változókat, hacsak nincs más lehetőség, pont. Ilyen apróságokhoz rendben van, de szerintem fontos, hogy korán rájöjj, hogyan kell helyesen csinálni a dolgokat.
A globális változók általában elég borzalmasak… kivéve, ha csak hivatkozásként használod őket, és soha nem változtatod meg őket egy függvényen belülről. Miért számít ez? Mert ha van tíz függvényed, amelyek mind ugyanazt a változót használják, és mondjuk, megváltoztatják, amit csinálnak az adott változó alapján, és bármelyikük esetleg megváltoztathatja, hirtelen az összes függvény viselkedése rendkívül kiszámíthatatlanná válik.
Azt, amivel ehelyett meg kell ismerkedned, az a függvények kimenetének rögzítése. Kimeneti adatokat, objektumokat, szöveget, bármit, amit akarsz, majd ezt a kimenetet tárolod valamiben a függvény meghívásakor. Amikor a függvény befejeződik, ez a tároló tartalmazza a szükséges értéket.
Ez sokkal könnyebben követhető, mert ilyen sorokat kapsz a végén:
$variable = Function-Name -Parameter1 'ParameterValue'
Egy pillantásra tudod, hogy ez a változó tartalmazza az adott függvény kimenetét, és csak meg kell nézned a függvényt, hogy lásd, mit kapsz. Hasonlítsd össze a globális változókkal:
$global:Var = 'initial value'Function-Name -Parameter1 'ParameterValue'# check the value of $global:Var$global:Var
És fogalmad sincs, hogy ez a változó még mindig az eredeti értéket tartalmazza-e. Ez a hatás fokozódik, ha elkezded erősen használni a globális változókat, és nagyon nehéz lesz követned, hogy mit csinál a saját kódod.
Szóval, mit teszel, hogy a dolgok ésszerűek maradjanak?
A függvényed példájában:
function Get-DiskSize { param( $Drives ) $Drives | ForEach-Object { $Vol = ("$_" + ":") $WMIPriorDisk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$Vol'" | Select-Object Size, FreeSpace $PriorDiskObject = @{ DriveLetter = $Vol DiskSizePrior = "{0:N2}" -f ($WMIPriorDisk.Size / 1GB) DiskFreePrior = "{0:N2}" -f ($WMIPriorDisk.FreeSpace / 1GB) } Write-Output $PriorDiskObject } }$Drives = (::GetDrives() | Where-Object {$_.DriveType -eq "Fixed"} | Select-Object -ExpandProperty 'Name').Replace(":\","")$DisksPrior = Get-DiskSize -Drives $Drives
Hadd bontsam le:
- Először a függvények. Definiáld a függvényeidet, mielőtt bármi mást tennél. A függvényeket bárhol használhatod a kódban, ezért sokkal hasznosabb, ha van egy következetes hely, ahol ellenőrizheted a függvényeidet. Egyszerűbb, ha az elején tartod őket, így nem kell az egész szkriptben keresgélned, hogy hova tetted azt a függvényt, amit meg kell változtatnod.
- Paraméterek definiálása. Minden olyan adatot, amelyet a függvényednek a tágabb szkriptből kell használnia, meg kell határoznod a paramétereiben. Így egy pillantással láthatod, hogy a függvénynek milyen adatokra van szüksége, és biztos lehetsz benne, hogy a megfelelő adatokat fogod megadni neki, és véletlenül nem mungóztad el valahol máshol a szkriptben.
- Kimenet!
Write-Output
egy nagyon egyértelmű módja a dolognak, de alapértelmezés szerint egyszerűen csak hagyjuk, hogy az adatok “leessenek” a kimeneti folyamba azáltal, hogy nem kapjuk el őket (pl. hagyjuk, hogy egy sorban álljanak önmagukban), akkor is kimenetre kerülnek. Jobban szeretem az egyértelműbb szintaxist, amikor megadjuk, hogy “igen, ezt az adatot kiadom”. - Capturing! A
$var = function-name
elvégzése alapvetően azt jelenti, hogy “hívd meg ezt a függvényt, és rögzítsd a kimenetet a$var
változóba”. Ez lehetővé teszi, hogy később felhasználja ezeket az adatokat, és mivel ugyanott definiálja, ahol használja, sokkal könnyebb követni, hogy mit csinál a kódjával. - Objektumtípusok. A PSObject típust használod, és hashtable segítségével konstruálod meg. Amit én csinálok, az nagyon hasonló, de általában a PsCustomObject típus rugalmasabbnak bizonyul mindenhez, amit el kell végezned. Könnyebben formázható, és zökkenőmentesebben működik az összes cmdlettel.
-
Kiegészítő apróságok: Azok a szögletes zárójelek az úgynevezett “attribútumok”. Ezek olyan extra bitek, amelyeket különböző felhasználási módokkal alkalmazhatsz a függvényeidhez.
kijelenti, hogy ez egy “fejlett függvény” (számomra buta név, de ezt választották). Alapvetően ez lehetővé teszi, hogy használd azokat az alapértelmezett paramétereket, amelyeket a PS lehetővé tesz a függvények számára. Megtehetsz olyan dolgokat, mint például a
Write-Verbose
hívása, hogy információt hagyj hátra arról, amit csinálsz, ami általában el van rejtve (mert általában nincs rá szükség), de aztán meghívhatod a függvényt a-Verbose
paraméterrel, hogy lásd az üzeneteket (ha valami nem úgy megy, ahogy vártad, így láthatod, hol rontja el).attribútumokat lehet definiálni minden ilyen paraméterhez. Meghatározhatod a konkrét pozíciókat, azt, hogy kötelezőek-e, és sok más dolgot, például azt, hogy elfogadják-e a csővezeték bemenetét.
Szóval, ezt szem előtt tartva, íme, hogyan kezelném én magam ezt a függvényt:
function Get-DiskSize { param( ] $Drives ) process { $Drives | ForEach-Object { $Vol = ("$_" + ":") Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$Vol'" | Select-Object -Property @{ Name = 'TotalSpace' Expression = { "{0:N2}" -f ($_.Size / 1GB) } }, @{ Name = 'FreeSpace' Expression = { "{0:N2}" -f ($_.FreeSpace / 1GB) } } } } }$DisksPrior = (::GetDrives() | Where-Object {$_.DriveType -eq "Fixed"} | Select-Object -ExpandProperty 'Name').Replace(":\", "") | Get-DiskSize
Többé-kevésbé csak lerövidítettem, csináltam néhány fantáziadúsabb dolgot, és a csővezetékkel együtt dolgoztattam, így kevesebb lépésben tudod ugyanazt a dolgot elvégezni. Elismerem, hogy valószínűleg teljesen túlterheltelek itt, úgyhogy kérlek, ne félj bökdösni darabonként, és kérdezz bármit, amiben nem vagy biztos. Vannak itt olyan dolgok, amiket fentebb nem említettem, de hé! Használhatod bőségesen a Get-Help
vagy a Google-t, és én itt vagyok mindenben, amihez “dióhéjban” magyarázatra van szükséged, vagy amit nehezen értesz meg.
Sok szerencsét odakint, kicsit vad lehet 😀
.