Powershell fonksiyonel bi dersan re ne oksîmoron e, ez wê garantî dikim

Hey Habr! Wergera gotarê pêşkêşî we dikim "PowerShell fonksiyonel bi dersan.
Ez soz didim ku ew ne oksîmoron e"
ji hêla Christopher Kuech ve.

Dibe ku paradîgmayên bernamesaziya objekt-oriented û fonksiyonel bi hevûdu re dijber xuya bikin, lê her du jî di Powershell de wekhev têne piştgirî kirin. Hema hema hemî zimanên bernamesaziyê, bikêrhatî an na, xwedî îmkanên ji bo girêdana nav-nirxa dirêjkirî ne; Ders, mîna struktur û tomar, tenê nêzîkatiyek in. Ger em karanîna xwe ya Dersan bi girêdana nav û nirxan re sînordar bikin, û ji têgînên bernamesaziyê yên giran-objektparêz ên wekî mîras, pirmorfîzm, an guhêrbariyê dûr bixin, em dikarin ji feydeyên wan sûd werbigirin bêyî ku koda xwe tevlihev bikin. Wekî din, bi lê zêdekirina rêbazên veguheztina celebê neguhêrbar, em dikarin koda xweya fonksiyonel bi Dersan dewlemend bikin.

Magic of castes

Castes di Powershell de yek ji taybetmendiyên herî hêzdar in. Gava ku hûn nirxek diavêjin, hûn xwe dispêrin kapasîteyên destpêkê û pejirandinê yên nepenî ku hawîrdor li serîlêdana we zêde dike. Mînakî, bi tenê avêtina rêzek di [xml] de dê wê di nav koda parser de bimeşîne û darek xml-ya tevahî çêbike. Em dikarin ji bo heman armancê di koda xwe de Ders bikar bînin.

Hashtables avêtin

Ger çêkerek we tune be, hûn dikarin bêyî yek bidomînin bi avêtina hashtable li ser celebê pola xwe. Ji bîr nekin ku hûn taybetmendiyên pejirandinê bikar bînin da ku ji vê nimûneyê sûd werbigirin. Di heman demê de, em dikarin taybetmendiyên tîpkirî yên polê bikar bînin da ku mentiqa destpêkê û pejirandinê hîn kûrtir bimeşînin.

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
}

Wekî din, avêtin ji bo bidestxistina hilberek paqij dibe alîkar. Ger hûn pêşî van haştablekan bavêjin çînekê, derketina berhevoka hashtable Cluster ya ku ji Format-Table re derbas bûye bi ya ku hûn distînin bidin ber hev. Taybetmendiyên çînek her gav bi rêza ku li wir têne destnîşan kirin têne navnîş kirin. Ji bîr nekin ku li pêşiya hemî taybetmendiyên ku hûn nexwazin di encaman de xuya bibin, keyworda veşartî lê zêde bikin.

Powershell fonksiyonel bi dersan re ne oksîmoron e, ez wê garantî dikim

Çêkirina wateyan

Ger çêkerek we bi yek argumanan hebe, avêtina nirxek ji celebê pola we re dê nirxê ji çêkerê xwe re derbas bike, li wir hûn dikarin mînakek çîna xwe bidin destpêkirin.

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"

Li ser rêzê avêtin

Her weha hûn dikarin rêbaza pola [string] ToString() bişopînin da ku mentiqê li pişt temsîla stêlê diyar bikin, wek mînak bikaranîna navberkirina rêzikê.

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'"

Mînakên serialîzekirî avêtin

Cast destûrê deserialization ewle. Mînakên li jêr dê têk biçin ger daneya li Cluster-ê bi taybetmendiya me negirin

# Валидация сериализованных данных

[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"

Di koda weya fonksiyonê de cih digire

Bernameyên fonksiyonel pêşî strukturên daneyê diyar dikin, dûv re bernameyê wekî rêzek veguherînan li ser strukturên daneya neguhêrbar bicîh dikin. Tevî bandora nakok, ders bi rastî ji we re dibe alîkar ku hûn koda fonksiyonel binivîsin bi saya şêwazên veguheztinê yên celeb.

Ma Powershell ku ez dinivîsim fonksiyonel e?

Pir kesên ku ji C# an paşnavên mîna wan têne Powershell-ê, ku dişibihe C#-ê, dinivîsin. Bi kirina vê yekê, hûn ji karanîna têgehên bernamesaziya fonksiyonel dûr dikevin û îhtîmal e ku hûn bi giranî sûd werbigirin nav bernamesaziya objekt-oriented li Powershell an fêrbûna bêtir di derbarê bernamesaziya fonksiyonel de.

Ger hûn bi giranî xwe dispêrin veguherîna daneyên neguhêrbar bi karanîna lûleyên (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object, hwd. - we şêwazek fonksiyoneltir heye û hûn ê ji karanîna Powershell sûd werbigirin. dersên bi şêwazek fonksiyonel.

Bikaranîna fonksiyonê ya dersan

Castes, her çend ew hevoksaziyek alternatîf bikar tînin jî, tenê nexşeyek di navbera du domanan de ne. Di hêlînê de, hûn dikarin bi karanîna ForEach-Object rêzek nirxan nexşînin.

Di mînaka jêrîn de, çêkerê Node-ê her carê ku Datumek tê avêtin tê darve kirin, û ev fersendê dide me ku em qas kodek rast nenivîsin. Wekî encamek, xeta boriyê me balê dikişîne ser lêpirsîn û berhevkirina daneya daxuyandî, dema ku dersên me parkirin û pejirandina daneyê digirin.

# Пример комбинирования классов с конвейерами для 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

Dersa pakkirinê ji bo ji nû ve karanîna

Tiştek bi qasî ku xuya dike ne baş e

Mixabin, çîn nikarin ji hêla modulan ve bi heman rengî wekî fonksiyon an guhêrbar werin derxistin; lê hin hîle hene. Em bibêjin dersên we di pelê ./my-classes.ps1 de hatine diyarkirin

  • Hûn dikarin pelek bi çînên dotsource:. ./my-classes.ps1. Ev ê di çarçoveya weya heyî de my-classes.ps1 pêk bîne û hemî çînên ji pelê li wir diyar bike.

  • Hûn dikarin modulek Powershell biafirînin ku hemî API-yên weyên xwerû (cmdlet) derdixe û guhêrbara ScriptsToProcess = "./my-classes.ps1" di manîfestoya moduleya xwe de bicîh bike, bi heman encamê: ./my-classes.ps1 dê di jîngeha te.

Kîjan vebijarka ku hûn hilbijêrin, ji bîr mekin ku pergala celebê ya Powershell nikare celebên heman navî yên ku ji cîhên cihê hatine barkirin çareser bike.
Tewra ku we du çînên wekhev bi heman taybetmendiyan ji cîhên cihêreng barkirin, hûn xeternak in ku hûn bikevin nav pirsgirêkan.

Rê li pêş e

Awayê çêtirîn ku hûn ji pirsgirêkên çareseriya tîpê dûr bisekinin ev e ku hûn çu carî dersên xwe ji bikarhêneran re dernexînin. Li şûna ku hûn li bendê bin ku bikarhêner celebek bi polê diyarkirî derxînin, fonksiyonek ji modula xwe derxînin ku hewcedariya rasterast gihîştina polê ji holê radike. Ji bo Cluster, em dikarin fonksiyonek New-Cluster derxînin ku dê komên parametreyên bikarhêner-heval piştgirî bike û Klusterek vegerîne.

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

Din çi bixwînin

Derbarê Dersan
Parastina PowerShell
Bernamekirina fonksiyonel di PowerShell de

Source: www.habr.com

Add a comment