Po operatorze trójwartościowym i współbieżnej pętli ForEach przyszedł czas na Null-e.
Null to takie bydlę, które z jednej strony jest całkiem wygodnym konceptem, a z drugiej przysparza programistom (i twórcom języków programowania) mnóstwo kłopotów.
Null z definicji oznacza brak wartości. Nie: zero. Nie: pusty ciąg znaków. Nie. BRAK wartości.
Najwięcej problemów z NULL-em pojawia się przy operacjach boole-owskich: czy null AND true da w wyniku false? A może null?
Czy null OR true da w wyniku true? false? null?
Hmmm…
Niektóre języki próbują to rozwiązać poprzez wprowadzenie specjalnej wartości UNKNOWN: null AND true da w wyniku UNKNOWN. 3 + NULL - również. Ale tu pojawia się problem wyższego rzędu: skoro UNKNOWN samo w sobie jest wartością (specjalną, ale jednak), trzeba dorobić logikę, która ją uwzględnia... czy UNKNOWN and NULL dają na wyjściu UNKNOWN? A może NULL? A może 42? Hm.
Inne języki zakładają po prostu, że jakakolwiek operacja z NULL-em da w wyniku NULL.
Jeszcze inne konwertują niejawnie NULL na 0.
Różnych algorytmów postępowania z NULL-ami jest całkiem sporo (niektóre się wzajemnie wykluczają!), ale ja dziś nie o tym.
Ja dziś o tym, jak rozpoznać NULL-a w Powershell oraz co z tego wynika.
Zacznę od tego, że implementacja NULL w Powershell nie jest byt elegancka. W wersji 5.x na przykład można było zrobić coś takiego:
$zmienna = $null
$zmienna -eq $null
Wynik powyższego dawał na wyjściu True. Ale już:
[string] $innazmienna = $null
$innazmienna -eq $null
… generował na wyjściu False. Wystarczy więc dodać deklarację typu, żeby się rozjechało. Jeżeli chcieliśmy sprawdzić "null-owatość" zmiennej typu string, musieliśmy się łapać "brudnych" chwytów typu [String]::Empty lub im podobnych. Groch z kapustą.
Jeszcze gorzej było z NULL-ami zwracanymi przez zapytania SQL. Żeby sprawdzić, czy dostaliśmy NULL, trzeba było używać [DBNull]::Value, co prowadziło do jeszcze większego zamieszania.
Powershell 7.0 próbuje to wszystko uporządkować - czy robi to prawidłowo czy nie, chyba nie da się jednoznacznie określić, krzaków po drodze jest mnóstwo. Ale jest postęp.
Ci z Czytelników, którzy liznęli w życiu nieco SQL-a wiedzą o istnieniu operatora COALESCE, który zwraca pierwszą napotkaną wartość parametru niebędącego NULL-em. Innymi słowy jeżeli a i b są NULL, a c i d nie są, wówczas COALESCE(a, b, c, d) zwróci wartość zmiennej c, bo jest to pierwszy parametr niebędący NULL. I tak dalej.
W Powershell 7 pojawił się operator ??, który robi mniej więcej to samo, tylko trochę inaczej:
$x = "iks"
$y = "igrek"
$z = "zet"
$a ?? $b ?? $c ?? $x ?? $y ?? $z
Powyższy kod da na wyjściu "iks", ponieważ zarówno $a jak też $b i $c są NULL, a $x jest pierwszą zmienną niebędącą NULL.
Drugim ważnym operatorem, który pojawił się w PS7, jest operator "podstaw jeżeli NULL", który najpierw sprawdza, czy po lewej stronie jest NULL i jeżeli tak, podstawia do lewej strony to, co jest po prawej, a jeżeli nie, to nic nie robi. Przykład:
$a ??= "literka a"
$a ??= "literka b"
$a ??= "literka c"
Tutaj na dzień dobry $a jest NULL (bo nie ma takiej zmiennej, a nieistniejące zmienne w PS są zawsze NULL), więc najpierw do $a zostanie podstawiony tekst "literka a". Potem próbujemy tam podstawić "literka b", ale operator ??= "widzi", że po lewej stronie ma już jakąś wartość ("literka a") i zignoruje podstawienie. To samo dzieje się w kolejnej linii, tej z literką c.
Wniosek końcowy? Operatory ?? oraz ??= mogą zaoszczędzić nam zbędnego klepania if-ów, ale trzeba ich używać z głową. Jak wszystkiego zresztą.
Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]
Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.