Čau Habr! Do pozornosti dávam preklad článku
Sľubujem, že to nie je oxymoron"
Objektovo orientované a funkčné programovacie paradigmy sa môžu zdať vo vzájomnom rozpore, ale obe sú v Powershell rovnako podporované. Takmer všetky programovacie jazyky, funkčné alebo nefunkčné, majú prostriedky na rozšírenú väzbu medzi názvom a hodnotou; Triedy, ako sú štruktúry a záznamy, sú len jedným prístupom. Ak obmedzíme naše používanie tried na viazanie mien a hodnôt a vyhneme sa náročným objektovo orientovaným programovacím konceptom, ako je dedičnosť, polymorfizmus alebo mutabilita, môžeme ich využiť bez toho, aby sme skomplikovali náš kód. Ďalej, pridaním nemenných metód konverzie typov môžeme obohatiť náš funkčný kód o triedy.
Kastová mágia
Castes sú jednou z najvýkonnejších funkcií v Powershell. Keď prenášate hodnotu, spoliehate sa na implicitné možnosti inicializácie a overovania, ktoré prostredie pridáva do vašej aplikácie. Napríklad jednoduchým prenesením reťazca do [xml] prebehne kód syntaktického analyzátora a vygeneruje sa kompletný xml strom. Na rovnaký účel môžeme použiť triedy v našom kóde.
Cast hashtables
Ak nemáte konštruktor, môžete pokračovať bez neho pretypovaním hašovacej tabuľky na váš typ triedy. Nezabudnite použiť overovacie atribúty, aby ste mohli naplno využiť tento vzor. Zároveň môžeme použiť typizované vlastnosti triedy na spustenie ešte hlbšej inicializačnej a validačnej logiky.
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
}
[Cluster]@{
Service = "MyService"
FlightingRing = "PROD"
Region = "EastUS"
Index = 2
}
Okrem toho odlievanie pomáha získať čistý výstup. Porovnajte výstup poľa hašovacej tabuľky klastra odovzdaného do Format-Table s tým, čo získate, ak tieto hašovacie tabuľky prvýkrát prenesiete do triedy. Vlastnosti triedy sú vždy uvedené v poradí, v akom sú tam definované. Nezabudnite pridať skryté kľúčové slovo pred všetky tie vlastnosti, ktoré nechcete, aby boli vo výsledkoch viditeľné.
Obsadenie významov
Ak máte konštruktor s jedným argumentom, odovzdaním hodnoty do vášho typu triedy sa hodnota odovzdá vášmu konštruktorovi, kde môžete inicializovať inštanciu vašej triedy
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
Cluster([string] $id) {
$this.Service, $this.FlightingRing, $this.Region, $this.Index = $id -split "-"
}
}
[Cluster]"MyService-PROD-EastUS-2"
Cast to line
Môžete tiež prepísať metódu triedy [string] ToString(), aby ste definovali logiku za reprezentáciou reťazca objektu, napríklad pomocou interpolácie reťazca.
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
[string] ToString() {
return $this.Service, $this.FlightingRing, $this.Region, $this.Index -join "-"
}
}
$cluster = [Cluster]@{
Service = "MyService"
FlightingRing = "PROD"
Region = "EastUS"
Index = 2
}
Write-Host "We just created a model for '$cluster'"
Cast serializované inštancie
Odliatok umožňuje bezpečnú deserializáciu. Nižšie uvedené príklady zlyhajú, ak údaje nespĺňajú naše špecifikácie v klastri
# Валидация сериализованных данных
[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"
Casty vo vašom funkčnom kóde
Funkčné programy najskôr definujú dátové štruktúry, potom implementujú program ako postupnosť transformácií nad nemennými dátovými štruktúrami. Napriek rozporuplnému dojmu vám triedy vďaka metódam konverzie typov skutočne pomáhajú pri písaní funkčného kódu.
Je Powershell, ktorý píšem, funkčný?
Veľa ľudí z C# alebo podobného prostredia píše Powershell, ktorý je podobný C#. Týmto spôsobom sa vzďaľujete od používania konceptov funkčného programovania a pravdepodobne by vám prospelo, keby ste sa intenzívne ponorili do objektovo orientovaného programovania v Powershell alebo sa dozvedeli viac o funkčnom programovaní.
Ak sa vo veľkej miere spoliehate na transformáciu nemenných údajov pomocou kanálov (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object atď. – máte funkčnejší štýl a budete mať prospech z používania Powershell triedy vo funkčnom štýle.
Funkčné využitie tried
Kasty, hoci používajú alternatívnu syntax, sú len mapovaním medzi dvoma doménami. V potrubí môžete mapovať pole hodnôt pomocou ForEach-Object.
V nižšie uvedenom príklade sa konštruktor Node spustí vždy, keď sa prenesie Dátum, čo nám dáva príležitosť vyhnúť sa písaniu veľkého množstva kódu. V dôsledku toho sa náš kanál zameriava na deklaratívne dopytovanie a agregáciu údajov, zatiaľ čo naše triedy sa starajú o analýzu a validáciu údajov.
# Пример комбинирования классов с конвейерами для separation of concerns в конвейерах
class Node {
[ValidateLength(3, 7)]
[string] $Name
[ValidateSet("INT", "PPE", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope", "WestEurope")]
[string] $Region
Node([string] $Name) {
$Name -match "([a-z]+)(INT|PPE|PROD)([a-z]+)"
$_, $this.Service, $this.FlightingRing, $this.Region = $Matches
$this.Name = $Name
}
}
class Datum {
[string] $Name
[int] $Value
[Node] $Computer
[int] Severity() {
$this.Name -match "[0-9]+$"
return $Matches[0]
}
}
Write-Host "Urgent Security Audit Issues:"
Import-Csv "./audit-results.csv" `
| ForEach-Object {[Datum]$_} `
| Where-Object Value -gt 0 `
| Group-Object {$_.Severity()} `
| Where-Object Name -lt 2 `
| ForEach-Object Group `
| ForEach-Object Computer `
| Where-Object FlightingRing -eq "PROD" `
| Sort-Object Name, Region -Unique
Trieda balenia na opätovné použitie
Nič nie je také dobré, ako sa zdá
Bohužiaľ, triedy nemožno exportovať modulmi rovnakým spôsobom ako funkcie alebo premenné; ale je tam pár trikov. Povedzme, že vaše triedy sú definované v súbore ./my-classes.ps1
-
Môžete dotsource súbor s triedami:. ./moje-triedy.ps1. Tým sa spustí súbor my-classes.ps1 vo vašom aktuálnom rozsahu a zadefinujú sa všetky triedy zo súboru v ňom.
-
Môžete vytvoriť modul Powershell, ktorý exportuje všetky vaše vlastné rozhrania API (cmdlets) a nastaviť premennú ScriptsToProcess = "./my-classes.ps1" v manifeste modulu s rovnakým výsledkom: ./my-classes.ps1 sa spustí v vaše prostredie.
Bez ohľadu na to, ktorú možnosť si vyberiete, majte na pamäti, že systém typov Powershell nedokáže rozlíšiť typy s rovnakým názvom načítané z rôznych miest.
Aj keď načítate dve rovnaké triedy s rovnakými vlastnosťami z rôznych miest, riskujete, že narazíte na problémy.
Cesta vpred
Najlepší spôsob, ako sa vyhnúť problémom s rozlíšením typov, je nikdy nevystavovať svoje triedy používateľom. Namiesto toho, aby ste od používateľa očakávali importovanie typu definovaného triedou, exportujte funkciu z vášho modulu, ktorá eliminuje potrebu priameho prístupu k triede. Pre Cluster môžeme exportovať funkciu New-Cluster, ktorá bude podporovať užívateľsky prívetivé sady parametrov a vráti Cluster.
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
}
function New-Cluster {
[OutputType([Cluster])]
Param(
[Parameter(Mandatory, ParameterSetName = "Id", Position = 0)]
[ValidateNotNullOrEmpty()]
[string] $Id,
[Parameter(Mandatory, ParameterSetName = "Components")]
[string] $Service,
[Parameter(Mandatory, ParameterSetName = "Components")]
[string] $FlightingRing,
[Parameter(Mandatory, ParameterSetName = "Components")]
[string] $Region,
[Parameter(Mandatory, ParameterSetName = "Components")]
[int] $Index
)
if ($Id) {
$Service, $FlightingRing, $Region, $Index = $Id -split "-"
}
[Cluster]@{
Service = $Service
FlightingRing = $FlightingRing
Region = $Region
Index = $Index
}
}
Export-ModuleMember New-Cluster
Čo ešte čítať
Zdroj: hab.com