Ang Functional Powershell nga adunay mga klase dili usa ka oxymoron, gigarantiyahan ko kini

Hoy Habr! Gipresentar ko sa imong pagtagad ang hubad sa artikulo "Functional nga PowerShell nga adunay mga Klase.
Gisaad ko nga dili kini usa ka oxymoron"
ni Christopher Kuech.

Ang Object-oriented ug functional nga mga paradigm sa programming mahimong daw magkasumpaki sa usag usa, apan parehas nga gisuportahan sa Powershell. Halos tanang programming language, functional man o dili, adunay mga pasilidad para sa extended name-value binding; Ang mga klase, sama sa mga istruktura ug mga rekord, usa lang ka pamaagi. Kung atong limitahan ang atong paggamit sa mga Klase ngadto sa pagbugkos sa mga ngalan ug mga mithi, ug likayan ang bug-at nga object-oriented programming concepts sama sa inheritance, polymorphism, o mutability, mahimo natong pahimuslan ang ilang mga benepisyo nga dili makomplikado ang atong code. Dugang pa, pinaagi sa pagdugang dili mabag-o nga mga pamaagi sa pagkakabig sa tipo, mahimo naton mapauswag ang among functional code sa mga Klase.

Ang salamangka sa mga kasta

Ang mga castes usa sa labing kusgan nga bahin sa Powershell. Kung nagbutang ka usa ka kantidad, nagsalig ka sa dili klaro nga pagsugod ug mga kapabilidad sa pag-validate nga gidugang sa palibot sa imong aplikasyon. Pananglitan, ang pag-cast lang og string sa [xml] magpadagan niini pinaagi sa parser code ug makamugna og kompletong xml tree. Mahimo natong gamiton ang mga Klase sa atong code alang sa samang katuyoan.

Ipagawas ang mga hashtable

Kung wala kay constructor, makapadayon ka nga walay usa pinaagi sa pagbutang ug hashtable sa klase sa imong klase. Ayaw kalimti ang paggamit sa mga kinaiya sa pag-validate aron mapahimuslan kini nga sumbanan. Sa parehas nga oras, magamit namon ang gi-type nga mga kabtangan sa klase aron makadagan ang labi ka lawom nga pagsugod ug lohika sa pag-validate.

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
}

Dugang pa, ang paghulma makatabang aron makakuha usa ka limpyo nga output. Itandi ang output sa Cluster hashtable array nga gipasa sa Format-Table sa unsay imong makuha kon una nimong isalibay kining mga hashtable sa usa ka klase. Ang mga kabtangan sa usa ka klase kanunay nga gilista sa han-ay diin sila gihubit didto. Ayaw kalimti nga idugang ang tinago nga keyword sa wala pa ang tanan nga mga kabtangan nga dili nimo gusto nga makita sa mga resulta.

Ang Functional Powershell nga adunay mga klase dili usa ka oxymoron, gigarantiyahan ko kini

Paglaraw sa mga kahulugan

Kung ikaw adunay usa ka konstruktor nga adunay usa ka argumento, ang paghulog sa usa ka kantidad sa imong klase nga klase ipasa ang kantidad sa imong konstruktor, diin mahimo nimong masugdan ang usa ka pananglitan sa imong klase

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"

Ibutang sa linya

Mahimo usab nimo nga i-override ang [string] ToString() class method aron ipasabot ang logic luyo sa representasyon sa string sa butang, sama sa paggamit sa string 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'"

I-cast ang serialized nga mga higayon

Gitugotan sa cast ang luwas nga deserialization. Ang mga pananglitan sa ubos mapakyas kung ang datos dili makatagbo sa among detalye sa Cluster

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

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

Mga cast sa imong functional code

Ang mga functional nga mga programa una nga naghubit sa mga istruktura sa datos, dayon ipatuman ang programa isip usa ka han-ay sa mga pagbag-o sa dili mausab nga mga istruktura sa datos. Bisan pa sa nagkasumpaki nga impresyon, ang mga klase makatabang kanimo sa pagsulat sa functional code salamat sa mga pamaagi sa pagkakabig sa tipo.

Magamit ba ang Powershell nga akong gisulat?

Daghang mga tawo nga gikan sa C # o parehas nga mga background ang nagsulat sa Powershell, nga parehas sa C #. Pinaagi sa pagbuhat niini, nagpalayo ka sa paggamit sa mga konsepto sa functional programming ug lagmit makabenepisyo gikan sa pag-diving pag-ayo ngadto sa object-oriented nga programming sa Powershell o pagkat-on og dugang mahitungod sa functional programming.

Kung nagsalig ka pag-ayo sa pagbag-o sa dili mausab nga datos gamit ang mga pipeline (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object, ug uban pa - aduna kay mas functional nga estilo ug makabenepisyo ka sa paggamit sa Powershell mga klase sa usa ka functional nga estilo.

Functional nga paggamit sa mga klase

Ang mga castes, bisan kung naggamit sila og alternatibong syntax, usa lang ka pagmapa tali sa duha ka dominyo. Sa pipeline, mahimo nimong mapa ang usa ka han-ay sa mga kantidad gamit ang ForEach-Object.

Sa panig-ingnan sa ubos, ang Node constructor gipatuman sa matag higayon nga ang usa ka Datum gisalibay, ug kini naghatag kanato sa oportunidad nga dili magsulat og patas nga gidaghanon sa code. Ingon usa ka sangputanan, ang among pipeline nagpunting sa deklaratibo nga pagpangutana sa datos ug pagtipon, samtang ang among mga klase nag-atiman sa pag-parse ug pag-validate sa datos.

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

Klase sa pagputos para magamit pag-usab

Wala’y ingon ka maayo sa ingon

Ikasubo, ang mga klase dili ma-eksport sa mga module sa parehas nga paagi sama sa mga gimbuhaton o mga variable; pero naay mga tricks. Ingnon ta nga ang imong mga klase gihubit sa file ./my-classes.ps1

  • Mahimo nimong dotsource ang usa ka file nga adunay mga klase:. ./akong-klase.ps1. Kini mopatuman sa my-classes.ps1 sa imong kasamtangan nga sakup ug ipasabut ang tanan nga mga klase gikan sa file didto.

  • Makahimo ka og Powershell module nga mag-eksport sa tanan nimong custom APIs (cmdlets) ug itakda ang ScriptsToProcess = "./my-classes.ps1" variable sa imong module manifest, nga adunay parehas nga resulta: ./my-classes.ps1 ipatuman sa imong palibot.

Bisan unsa nga kapilian ang imong pilion, hinumdomi nga ang sistema sa tipo sa Powershell dili makasulbad sa mga tipo sa parehas nga ngalan nga gikarga gikan sa lainlaing mga lugar.
Bisan kung nagkarga ka ug duha ka parehas nga klase nga adunay parehas nga mga kabtangan gikan sa lainlaing mga lugar, peligro ka nga adunay mga problema.

Ang paagi sa unahan

Ang labing kaayo nga paagi aron malikayan ang mga problema sa resolusyon sa tipo mao ang dili pagbutyag sa imong mga klase sa mga tiggamit. Imbis nga magdahom nga ang user mag-import ug klase nga gitino sa klase, i-export ang usa ka function gikan sa imong module nga magwagtang sa panginahanglan nga direktang ma-access ang klase. Para sa Cluster, mahimo namong i-export ang usa ka New-Cluster function nga mosuporta sa user-friendly parameter sets ug mobalik og 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

Unsa pa ang basahon

Mahitungod sa mga Klase
Depensiba nga PowerShell
Functional Programming sa PowerShell

Source: www.habr.com

Idugang sa usa ka comment