PowerShell kotiček – Null

Tokrat si bomo ogledali, kako s PowerShellom obravnavamo »nevrednost« oz. neobstoj vrednosti določene spremenljivke, tako imenovani NULL . Razvijalcem je koncept zelo dobro poznan, zato si bomo tu ogledali PowerShell pristop do tega. Neobravnava in/ali napačen pristop do neobstoječe vrednosti v najboljšem primeru povzroči nenačrtovan zaključek skripte/programa, v najslabšem pa pride do »poškodovanja« podatkov in neprijetnih situacij in škode, kar si lahko preberete, če pogooglate ime Joseph Tartaro, ki si je geekovsko privoščil prilagojeno registrsko tablico z napisom NULL, nato pa »pokasiral« vse prometne prekrške, kjer je bila tablica povzročitelja neznana oz. ni bila vpisana v baze.

Pod NULL si torej predstavljamo neznano oz. »prazno« vrednost. Spremenljivka v skripti je NULL dokler ji prvič ne dodelimo vrednosti.

Powershell vsebuje avtomatsko spremenljivko $null, ki predstavlja omenjeni NULL, in jo lahko uporabljamo za prirejanje drugim spremenljivkam,  uporabljamo v primerjavah vrednosti in na mestu NULL v zbirkah, pri čemer PowerShell obravnava $null kot objekt, kar ga razlikuje od večine programskih jezikov.

Najbolj pogosta uporaba $null je pri primerjavah, kjer raziskujemo, če je določeni spremenljivki že bila dodeljena vrednost, na primer:

PS>$null -eq $nedefiniranaSpremenljivka
True

Zgodi se tudi, da smo se pri kodiranju zatipkali, PowerShell pa vidi zatipkano ime kot novo spremenljivko, ki seveda nima vrednosti, oz je NULL.

$null vrednosti bomo dobili tudi, kadar uporabljeni ukazi ne vrnejo nobene vrednosti.

PS> function Get-Nothing {}
PS> $value = Get-Nothing
PS> $null -eq $value
True

Če uporabljamo $null v tekstovnih spremenljivkah, bo le-ta predstavljena s praznim nizom.

PS>$vrednost=$null
PS>write-output »Vrednost je ($vrednost)«
Vrednost je ()

Ko je $null uporabljen v numerični enačbi, bo rezultat nepravilen, če že ne bo prišlo do napake, saj bo v nekaterih primerih $null obravnavan kot 0, v drugih pa bo celoten rezultat enak $null.  Običajno je to odvisno od vrstnega reda vrednosti v enačbi:

PS> $null * 5
PS> $null -eq ( $null * 5 )
True
 
PS> 5 * $null
0

PS> $null -eq ( 5 * $null )
False

Seznami nam omogočajo , da dostopamo do vrednosti na podlagi indeksa. Če to poskušamo narediti na nedefiniranem seznamu, bomo seveda pridelali napako.

PS> $value = $null
PS> $value[10]
    Cannot index into a null array.
    At line:1 char:1

Če pa imamo definiran seznam, a skušamo dostopati do elementa, ki ga ni v seznamu, dobimo $null rezultat.

$array = @( 'one','two','three' )
$null -eq $array[100]
True

Pri sklicevanju na lastnost objekta, ki le-te lastnosti nima, Powershell vrne vrednost $null,  enako kot v primeru nedefinirane spremenljivke.

PS> $null -eq $nedefinirana.izmisljenalastnost
True

PS> $date = Get-Date
PS> $null -eq $date.izmisljenalastnost
True

Pri sklicu na metodo $null objekta, pa se hec konča in pridelamo napako.

PS> $value = $null
PS> $value.toString()
You cannot call a method on a null-valued expression.

Kadarkoli vidim frazo “You cannot call a method on a null valued expression” je prva stvar, ki jo naredim, da poiščem kje kličem metodo na spremenljivko, brez da bi prej preveril, če je $null.

V vseh zgoraj prikazanih primerjavah smo $null uporabljali na levi strani primerjave, t.j.

If $null -eq $vrednost

To je povsem namerno in sodi med Powershellove primere dobre prakse. Uporaba na desni v nekaterih primerih  ne vodi do pričakovanega rezultata. Recimo:

if ( $value -eq $null )
{
    'Seznam je $null'
}
if ( $value -ne $null )
{
    'Seznam ni $null'
}

Če spremenljivke $value ne definiramo, potem bo zgornja koda izpisala ‘Seznam je $null’.

Pa si oglejmo poseben primer, ko seznam je definiran, a vsebuje $null.

$value = @( $null )

V tem primeru noben od zgornjih pogojev ne bo $true (pri -eq primerjavi bo PowerShell primerjal vsak element seznama, in tako našel vsebovani $null. -ne pa bo prav tako vrnil $false, saj bo iskal vse kar je različno od $null in v tem primeru je definiran, neprazen seznam.

Če spipamo $null v ForEach-Object cmdlet, bo le ta zanj zgeneriral cikel in ga ne moremo tako uporabiti za neobstoj vrednosti.

PS> ".txt", $null, ".pdf" | Foreach {"test"}
test
test
test

Pri preverjanju na prisotnost $null (tj. odsotnost vrednosti) pa moramo biti pozorni še na izvir podatkov, saj so $null za nekatere vire različni. Preverjati moramo tako $null, [String]::Empty, [DBNull]::Value in [System.Management.Automation.Language.NullString]::Value, ustrezno seveda glede na problem, s katerim se ukvarjamo.

Dodaj odgovor

Vaš e-naslov ne bo objavljen. * označuje zahtevana polja