Functional Powershell nrog cov chav kawm tsis yog oxymoron, Kuv lav nws

Hlo Habr! Kuv nthuav qhia rau koj mloog cov lus txhais ntawm tsab xov xwm "Functional PowerShell nrog Chav Kawm.
Kuv cog lus tias nws tsis yog oxymoron "
los ntawm Christopher Kuech.

Object-oriented thiab functional programming paradigms yuav zoo li tsis sib haum nrog ib leeg, tab sis ob qho tib si muaj kev txhawb nqa sib npaug hauv Powershell. Yuav luag txhua hom lus programming, ua haujlwm lossis tsis ua haujlwm, muaj chaw rau txuas ntxiv lub npe-tus nqi khi; Cov chav kawm, zoo li cov qauv thiab cov ntaub ntawv, tsuas yog ib txoj hauv kev. Yog tias peb txwv peb cov kev siv Cov Chav Kawm rau kev khi cov npe thiab qhov tseem ceeb, thiab zam cov khoom hnyav-oriented programming cov ntsiab lus xws li qub txeeg qub teg, polymorphism, los yog mutability, peb muaj peev xwm coj kom zoo dua ntawm lawv cov txiaj ntsig yam tsis muaj teeb meem peb cov cai. Tsis tas li ntawd, los ntawm kev ntxiv hom kev hloov pauv tsis hloov pauv, peb tuaj yeem txhawb nqa peb cov lej ua haujlwm nrog Chav Kawm.

Cov khawv koob ntawm castes

Castes yog ib qho tseem ceeb tshaj plaws hauv Powershell. Thaum koj nrum tus nqi, koj tab tom tso siab rau qhov pib ua tsis tiav thiab muaj peev xwm siv tau qhov chaw ntxiv rau koj daim ntawv thov. Piv txwv li, yooj yim nrum ib txoj hlua hauv [xml] yuav khiav nws los ntawm parser code thiab tsim kom tiav ib tsob ntoo xml. Peb tuaj yeem siv Chav Kawm hauv peb cov cai rau tib lub hom phiaj.

Cam khwb cia hashables

Yog tias koj tsis muaj tus tsim qauv, koj tuaj yeem txuas ntxiv yam tsis muaj ib qho los ntawm kev ua tus hashable rau koj hom chav kawm. Tsis txhob hnov ​​​​qab siv tus cwj pwm validation los ua kom zoo dua ntawm tus qauv no. Nyob rau tib lub sijhawm, peb tuaj yeem siv cov cuab yeej ntaus ntawv hauv chav kawm kom khiav txawm tias qhov pib sib sib zog nqus thiab siv tau cov logic.

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
}

Tsis tas li ntawd, casting pab kom tau txais cov zis huv. Sib piv cov zis ntawm Cluster hashtable array dhau mus rau Format-Table nrog dab tsi koj tau txais yog tias koj xub nrum cov hashtables rau hauv chav kawm. Cov khoom ntawm ib chav kawm yeej ib txwm teev nyob rau hauv qhov kev txiav txim uas lawv tau txhais nyob rau ntawd. Tsis txhob hnov ​​​​qab ntxiv cov ntsiab lus zais ua ntej tag nrho cov khoom uas koj tsis xav pom hauv cov txiaj ntsig.

Functional Powershell nrog cov chav kawm tsis yog oxymoron, Kuv lav nws

Nthuav cov ntsiab lus

Yog tias koj muaj tus tsim qauv nrog ib qho kev sib cav, muab tus nqi rau koj hom chav kawm yuav dhau tus nqi rau koj tus tsim, uas koj tuaj yeem pib ua piv txwv ntawm koj chav kawm.

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"

Cam khwb cia rau kab

Koj tuaj yeem hla dhau [txoj hlua] ToString() chav kawm txoj hauv kev los txhais cov logic tom qab tus kwv txoj hlua sawv cev, xws li siv txoj hlua interpolation.

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 serialized piv txwv

Cast tso cai rau kev nyab xeeb deserialization. Cov piv txwv hauv qab no yuav ua tsis tau yog tias cov ntaub ntawv tsis ua raws li peb cov lus qhia hauv Cluster

# Валидация сСриализованных Π΄Π°Π½Π½Ρ‹Ρ…

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

Castes nyob rau hauv koj functional code

Cov kev pabcuam ua haujlwm ua ntej txhais cov qauv ntaub ntawv, tom qab ntawd siv qhov kev pabcuam raws li kev hloov pauv ntawm cov ntaub ntawv tsis hloov pauv. Txawm hais tias muaj qhov tsis sib xws, cov chav kawm yeej pab koj sau cov lej ua haujlwm ua tsaug rau hom kev hloov pauv hloov pauv.

Puas yog Powershell kuv sau ua haujlwm tau?

Ntau tus neeg tuaj ntawm C# lossis keeb kwm zoo sib xws tau sau Powershell, uas zoo ib yam li C#. Los ntawm kev ua qhov no, koj tab tom khiav tawm ntawm kev siv lub tswv yim ua haujlwm zoo thiab yuav tau txais txiaj ntsig los ntawm kev dhia dej hnyav rau hauv cov phiaj xwm taw qhia hauv Powershell lossis kawm ntxiv txog kev ua haujlwm ua haujlwm.

Yog tias koj vam khom rau kev hloov pauv cov ntaub ntawv tsis hloov pauv siv cov kav dej (|), Qhov twg-Tswj, ForEach-Object, Xaiv-Object, Pawg-Object, Sort-Object, thiab lwm yam - koj muaj qhov ua haujlwm zoo dua thiab koj yuav tau txais txiaj ntsig los ntawm kev siv Powershell chav kawm nyob rau hauv ib tug functional style.

Kev siv cov chav kawm ua haujlwm

Castes, txawm hais tias lawv siv lwm cov syntax, tsuas yog ib daim ntawv qhia ntawm ob lub npe. Hauv cov raj xa dej, koj tuaj yeem ua daim ntawv qhia txog qhov tseem ceeb uas siv ForEach-Object.

Hauv qhov piv txwv hauv qab no, Node constructor raug tua txhua zaus Datum raug pov tseg, thiab qhov no muab sijhawm rau peb kom tsis txhob sau cov lej ncaj ncees. Raws li qhov tshwm sim, peb cov kav dej tsom mus rau kev tshaj tawm cov ntaub ntawv querying thiab aggregation, thaum peb cov chav kawm saib xyuas cov ntaub ntawv parsing thiab validation.

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ комбинирования классов с ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°ΠΌΠΈ для 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

Chav kawm ntim khoom siv rov qab siv dua

Tsis muaj dab tsi zoo li nws zoo li

Hmoov tsis zoo, cov chav kawm tsis tuaj yeem raug xa tawm los ntawm cov modules tib yam li kev ua haujlwm lossis kev hloov pauv; tab sis muaj ib co tricks. Wb hais tias koj cov chav kawm tau txhais hauv cov ntaub ntawv ./my-classes.ps1

  • Koj tuaj yeem dotsource cov ntaub ntawv nrog cov chav kawm:. ./my-classes.ps1. Qhov no yuav ua rau kuv-classes.ps1 hauv koj qhov tam sim no thiab txhais tag nrho cov chav kawm los ntawm cov ntaub ntawv muaj.

  • Koj tuaj yeem tsim Powershell module uas xa tawm tag nrho koj cov kev cai APIs (cmdlets) thiab teeb tsa ScriptsToProcess = "./my-classes.ps1" sib txawv hauv koj qhov module manifest, nrog rau cov txiaj ntsig zoo ib yam: ./my-classes.ps1 yuav ua tiav hauv koj ib puag ncig.

Txawm koj xaiv qhov twg los xij, nco ntsoov tias Powershell hom system tsis tuaj yeem daws cov hom tib lub npe thauj khoom los ntawm ntau qhov chaw.
Txawm hais tias koj thauj khoom ob chav kawm zoo ib yam nrog cov khoom qub los ntawm ntau qhov chaw, koj pheej hmoo khiav mus rau qhov teeb meem.

Txoj kev rau pem hauv ntej

Txoj hauv kev zoo tshaj los zam cov teeb meem daws teeb meem yog kom tsis txhob nthuav tawm koj cov chav kawm rau cov neeg siv. Tsis txhob cia siab tias tus neeg siv yuav import ib hom ntawv teev tseg, xa cov haujlwm los ntawm koj lub module uas tshem tawm qhov xav tau nkag mus rau chav kawm ncaj qha. Rau Cluster, peb tuaj yeem xa tawm qhov Tshiab-Cluster muaj nuj nqi uas yuav txhawb nqa cov neeg siv khoom tus phooj ywg cov teeb tsa thiab xa rov qab Pawg.

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

Dab tsi ntxiv nyeem

Hais txog Chav Kawm
Kev tiv thaiv PowerShell
Functional Programming hauv PowerShell

Tau qhov twg los: www.hab.com

Ntxiv ib saib