Powershell fungsional sareng kelas sanés oxymoron, kuring ngajamin éta

Héy Habr! Kuring nampilkeun ka perhatian anjeun tarjamahan artikel "PowerShell Fungsional sareng Kelas.
Abdi janji éta sanés oxymoron"
ku Christopher Kuech.

Paradigma pemrograman berorientasi obyék sareng fungsional sigana teu aya hubunganana, tapi duanana dirojong dina Powershell. Ampir kabéh basa program, fungsional atawa henteu, boga fasilitas pikeun ngariung ngaran-nilai nambahan; Kelas, sapertos struktur sareng rékaman, ngan ukur hiji pendekatan. Upami urang ngabatesan panggunaan Kelas pikeun ngariung nami sareng nilai, sareng ngahindarkeun konsép program berorientasi obyék beurat sapertos warisan, polimorfisme, atanapi mutabilitas, urang tiasa ngamangpaatkeun kauntunganana tanpa ngahesekeun kode kami. Salajengna, ku cara nambahkeun métode konversi tipe immutable, urang bisa enrich kode fungsi urang jeung Kelas.

Sihir kasta

Kasta mangrupikeun salah sahiji fitur anu paling kuat dina Powershell. Lamun anjeun tuang nilai a, anjeun ngandelkeun initialization implisit sarta kamampuhan validasi lingkungan nambahkeun kana aplikasi Anjeun. Contona, ngan saukur casting string dina [xml] bakal ngajalankeun eta ngaliwatan kode parser sarta ngahasilkeun tangkal xml lengkep. Urang tiasa nganggo Kelas dina kode urang pikeun tujuan anu sami.

Matak hashtables

Mun anjeun teu mibanda constructor a, Anjeun bisa neruskeun tanpa hiji ku casting hashtable kana tipe kelas anjeun. Tong hilap nganggo atribut validasi pikeun ngamangpaatkeun pola ieu. Dina waktos anu sami, urang tiasa nganggo sipat diketik kelas pikeun ngajalankeun logika initialization sareng validasi anu langkung jero.

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
}

Sajaba ti éta, casting mantuan pikeun meunangkeun kaluaran bersih. Bandingkeun kaluaran tina Asép Sunandar Sunarya Kluster hashtable dibikeun ka Format-Table kalawan naon anjeun meunang lamun mimiti tuang hashtables ieu kana kelas. Sipat hiji kelas sok didaptarkeun dina urutan nu maranéhna dihartikeun aya. Tong hilap nambihan kecap konci anu disumputkeun sateuacan sadaya pasipatan anu anjeun henteu hoyong katingali dina hasil.

Powershell fungsional sareng kelas sanés oxymoron, kuring ngajamin éta

Matak harti

Upami anjeun gaduh konstruktor sareng hiji argumen, tuang nilai kana jinis kelas anjeun bakal ngalihkeun nilai ka konstruktor anjeun, dimana anjeun tiasa ngamimitian conto kelas anjeun.

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"

Matak ka garis

Anjeun oge bisa override [string] ToString () métode kelas pikeun ngartikeun logika balik ngagambarkeun string obyék, kayaning maké interpolasi string.

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

Tuang instansi serialized

Tuang ngamungkinkeun deserialization aman. Conto di handap bakal gagal upami data henteu nyumponan spésifikasi kami dina Kluster

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

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

Castes dina kode fungsi Anjeun

Program fungsional mimiti nangtukeun struktur data, teras nerapkeun program salaku runtuyan transformasi leuwih struktur data immutable. Sanaos kesan anu kontradiktif, kelas leres-leres ngabantosan anjeun nyerat kode fungsional berkat metode konversi ngetik.

Naha Powershell anu kuring nyerat fungsional?

Seueur jalma anu asalna ti C # atanapi latar anu sami anu nyerat Powershell, anu sami sareng C #. Ku ngalakukeun ieu, anjeun ngajauhan tina ngagunakeun konsép program fungsional sareng sigana bakal nguntungkeun tina nyilem pisan kana program berorientasi objék dina Powershell atanapi diajar langkung seueur ngeunaan program fungsional.

Upami anjeun ngandelkeun pisan kana ngarobih data anu teu tiasa dirobih nganggo jalur pipa (|), Dimana-Objék, PikeunEach-Objék, Pilih-Objék, Grup-Objék, Urut-Objék, jsb - anjeun gaduh gaya anu langkung fungsional sareng anjeun bakal nguntungkeun tina ngagunakeun Powershell kelas dina gaya fungsional.

Pamakéan fungsional kelas

Kasta, sanaos ngagunakeun sintaksis alternatif, ngan ukur pemetaan antara dua domain. Dina jalur pipa, anjeun tiasa peta sajumlah nilai nganggo ForEach-Object.

Dina conto di handap ieu, konstruktor Node dieksekusi unggal waktos Datum tuang, sareng ieu masihan kami kasempetan pikeun henteu nyerat jumlah kode anu lumayan. Hasilna, pipa kami museurkeun kana pamundut data déklaratif sareng agrégasi, sedengkeun kelas kami ngurus parsing sareng validasi data.

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

Kelas bungkusan pikeun dianggo deui

Henteu aya anu saé sapertos sigana

Hanjakal, kelas teu bisa diékspor ku modul dina cara nu sarua salaku fungsi atawa variabel; tapi aya sababaraha trik. Hayu urang nyebutkeun kelas anjeun dihartikeun dina file ./my-classes.ps1

  • Anjeun tiasa dotsource file sareng kelas:. ./abdi-kelas.ps1. Ieu bakal ngaéksekusi my-classes.ps1 dina wengkuan anjeun ayeuna jeung nangtukeun sagala kelas tina file aya.

  • Anjeun tiasa nyiptakeun modul Powershell anu ngékspor sadaya API khusus anjeun (cmdlet) sareng nyetél variabel ScriptsToProcess = "./my-classes.ps1" dina manifes modul anjeun, kalayan hasil anu sami: ./my-classes.ps1 bakal dieksekusi dina lingkungan anjeun.

Naon waé pilihan anu anjeun pilih, émut yén sistem jinis Powershell henteu tiasa ngabéréskeun jinis nami anu sami anu dimuat ti tempat anu béda.
Sanaos anjeun ngamuat dua kelas anu sami sareng sipat anu sami ti tempat anu béda, anjeun résiko ngagaduhan masalah.

Jalan ka payun

Cara anu pangsaéna pikeun ngahindarkeun masalah resolusi jinis nyaéta henteu pernah ngalaan kelas anjeun ka pangguna. Gantina ekspektasi pamaké pikeun ngimpor hiji tipe kelas-diartikeun, ékspor fungsi tina modul anjeun nu eliminates kudu aksés ka kelas langsung. Pikeun Kluster, urang tiasa ngékspor fungsi Kluster Anyar anu bakal ngadukung set parameter anu ramah-pamaké sareng ngabalikeun Kluster.

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

Naon deui macana

Ngeunaan Kelas
PowerShell pertahanan
Pemrograman Fungsional dina PowerShell

sumber: www.habr.com

Tambahkeun komentar