Czy funkcja może zwracać null?



Czy funkcja może zwracać null?
Z technicznego punktu widzenia nie ma żadnych przeciwwskazań. W klauzuli RETURN każdej funkcji możemy przekazać wartość (zgodną z typem zadeklarowanym w definicji funkcji) lub brak wartości czyli nasz NULL. Funkcja się poprawnie skompiluje i po uruchomieniu zwróci nam ów null.


Create or replace function test_null return varchar2 is
begin
    return NULL;
end;
/

begin
  DBMS_OUTPUT.PUT_LINE('Return: '|| test_null);
  DBMS_OUTPUT.PUT_LINE('Return: '|| nvl(test_null,'null'));
END;
/

Statement processed.
Return: 
Return: null

A co na to Best Practices?
Nie wszystko co z technicznego punku widzenia jest dozwolone ma sens w praktyce. To, że funkcja może zwracać null nie znaczy, że powinna z logicznego punktu widzenia. A może jednak ten logiczny sens jest? 

Kiedyś przy jednym projekcie przygotowałam funkcję, która miała zwracać pewną wyliczoną wartość. Jednak nie zawsze była możliwość wyliczenia tej wartości. A co ważniejsze BRAK MOŻLIWOŚCI wyliczenia nie było błędem w tej aplikacji. Nadrzędny proces był zainteresowany wyliczoną wartością, tylko wtedy, gdy udało się ją poprawnie wyliczyć. O każdym innym przypadku - czy o braku możliwości wyliczenia czy o błędzie - proces nadrzędny nawet nie powinien być informowany.

W związku z tymi wymaganiami funkcja zwracała albo wyliczoną wartość albo brak wartości czyli nasz null. Null był zwracany, gdy wyliczenie wartości nie było możliwe lub w przypadku błędu. Rozróżniałam te sytuacje, bo w przypadku błędu dodatkowo błąd ten był oczywiście logowany. Niemniej błąd nie był propagowany wyżej.

W takiej sytuacji NULL jest poprawnym wynikiem działania funkcji.

Niestety niektórzy programiści są bardzo przeciwni zwracaniu NULL. Koledzy, którzy w swoim projekcie chcieli używać mojej funkcji sugerowali mi, że taka funkcja jest niezgodna z Best Practices i że powinnam w każdej sytuacji zwracać jakąś wartość.

Propozycja zmiany polegała na tym, by w klauzuli RETURN zwracać:

1. Albo wyliczona wartość, jeśli wyliczenie się udało
2. Albo informację, że wyliczyć wartości nie można z powodów które nie są błędem
3. Albo błąd, jeśli taki wystąpił

Oczywiście kategorycznie zaprotestowałam przeciwko wprowadzeniu tych zmian. Zwracanie w klauzuli RETURN różnych typów informacji, raz wyliczoną wartość, raz błąd, innym razem jeszcze co innego - to dopiero pogwałcenie Best Practices!

Absolutnie nie można używać zmiennych do różnych celów! Nie można w jednej zmiennej przechowywać np imienia ALBO nazwiska ALBO  adresu ALBO kodu błędu. Tak samo tutaj nie można w klauzuli RETURN zwracać ALBO wyliczonej wartości ALBO informacji o nie wyliczeniu ALBO o błędzie.

Ostatecznie okazało się, że jestem bardziej uparta (a może na moją korzyść przechylił fakt, że proces był już przetestowany i wdrożony na produkcję i jakakolwiek zmiana powodowałaby konieczność powtórki czasochłonnych testów) i funkcja dalej zwracała null ku frustracji kolegów :o

Przynajmniej mi się wydawało, że jestem uparta. Bo jednak koledzy byli uparci bardziej. Gdy po jakimś czasie ukradkiem przejrzałam kod projektu, okazało się, że nie poddali się. Moim oczom ukazał się taki oto fragment kodu:

vVal := nvl(moja_funkcja, 'NULL');

Spuśćmy na to kurtynę milczenia...

Null a funkcje boolean
Jednak nie we wszystkich sytuacjach zwracanie nulla jest uzasadnione i zrozumiałe. Chodzi o funkcje boolean. Funkcje boolean zwracają true lub false. Zwracanie w takiej funkcji trzeciej  informacji, czyli null, byłoby trudne do interpretacji, albo mówiąc wprost - kompletnie niezrozumiałe. 

Przykładowo mamy funkcję w aplikacji dla biblioteki, która ma sprawdzać, czy książka jest wypożyczona. Funkcja zwracałaby informację PRAWDA lub FAŁSZ. Zwrócenie w takiej funkcji NULL nie ma racjonalnego sensu. Owszem, technicznie się da, ale czy null w funkcjach boolean ma logiczne uzasadnienie? 

Podsumowanie
Funkcje, oprócz funkcji boolean, mogą jak najbardziej zwracać null. Warto jednak zawsze przed podjęciem takiej decyzji dokładnie przemyśleć wymagania wobec funkcji oraz znaczenie zwracanych wartości, w tym nulla. Jeśli zwracany null ma sens, logiczne uzasadnienie - to nie ma innych przeciwwskazań!

Null to brak informacji. A brak informacji też jest informacją. Także używajcie NULL  śmiało ale z sensem!

Komentarze