Programistyczne WTF jakie Was spotkały

5

Komentarz do klasy:

Klasa wykorzystywana przez nieużywane stare... Wyłączone z użycia w kodzie dnia 19-08-2015... W związku z zakomentowaniem metod w innych klasach, w niniejszej klasie zostały zakomentowane linijki zgłaszające błędy.

Całość ma jeszcze kilka linijek i jest w takim tonie :D

5
ErrorCodeEnum.SUCCESS
8
public static function charAt(int $position): callable
{
    if (empty($string)) {
        throw new \AssertionError('Empty string');
    }
    return $string[$position];
}

Pomyślicie pewnie że sensowna funkcja nie? Też tak myślałem, ale nie działa dla stringa "0". Czemu?

Ano dlatego że PHPowi się umyślało że empty("0") === true, bo "0" jest false-y. Ehhhhhhhhhhhh.

5

Dzisiaj takie dwa mikro-WTFy.

WTF1: Jest sobie interfejs zdefiniowany w bibliotece third-party. Ma zdefiniowaną publiczną metodę clone. Implementacje owego interfejsu w tejże bibliotece klonują stan obiektu prawdidłowo, tzn obiekt po sklonowaniu jest niezależny od oryginału i można bezpiecznie zmieniać jego stan bez ryzyka zepsucia oryginału. No i właśnie to mi było potrzebne i takie clone sobie wywołałem w swoim kodzie. Na code review dostaje komentarz - "ej, ale clone w naszych klasach implementujących ten interfejs nie działa, musisz to zmienić" :D

WTF2: Robię kursor do przechodzenia po pewnej kolekcji danych. Dla oszczędności alokacji, kursor ma własny bufor na dane, który może udostępnić, jednak jest ważny tylko do wywołania metody zmieniającej pozycję kursora. Metodę przechodzącą do następnego elementu nazwałem advance, bo przechodzi do następnego elementu, ale go nie zwraca. Na CR dostaję komentarz: "zmień to na next(). Odpisałem, że to nie zwraca następnego elementu, to dlaczego ma się nazywać next? Komentarz z CR: "W opisie masz "advances the cursor to the next item", więc powinno się nazywać next.

9

Pierwsze spotkanie z oprogramowaniem typu Enterprise.
SomeDomainNameStatusMessageNotificationMapperFactory
SomeDomainNameStatusMessageNotificationBodyBuilder
I setki podobnych generycznych klas. Właśnie przestało mnie to śmieszyć.

3

W C# polecieli trochę grubo z jednym tematem, z jednej strony fajne, z drugiej strony może prowadzić do małych wtfów.

Dawno temu w C# 6 dodali string interpolation

string.Format("{0} {1}", arg1, arg2);
można zastąpić:
$"{arg1} {arg2}"

wszystko fajnie, tylko że pod spodem jest wołane Format, jest trochę alokacji pamięci, tworzenie pod spodem StringBuildera itp, ogólnie dużo niepotrzebnej roboty w przypadku gdy np dodajemy taki string już do istniejącego StringBuildera:

StringBuilder sb = new();
sb.Append($"{arg1} {arg2}");

albo na przykład gdy podajemy message do asercji w której message nie będzie potrzebny bo warunek jest spełniony:

Debug.Assert(true, $"{arg1} {arg2}"); // zawsze przechodzi, nie ma potrzeby konstruowania stringa

w .NET 6.0 / C# 10 dodano więc InterpolatedStringHandler - taki string może być przekazany nie jako string, ale jako struktura z instrukcjami potrzebnymi do jego zbudowania. Pozwala to samemu obsłużyć (warunkowo) interpolację, wobec czego przykład ze StringBuilderem staje się automatycznie odpowiednikiem:

StringBuilder sb = new();
sb.Append(arg1);
sb.Append(' ');
sb.Append(arg2);

a w przykładzie z Assert budowanie stringa się w ogóle nie wykona jeśli warunek będzie spełniony.
I tu dochodzimy do małego wtfa:

var i = 0;
Debug.Assert(true, $"{i ++}");

wywołania metod, inkrementacje itp zostają zupełnie pominięte w przypadku niespełnienia warunku.
wartość i jest zależna od rezultatu asercji i w tym przypadku wynosi "0" (a jeszcze w .NET 5.0 / C# 9 wynosiła "1")
Mamy tu jakby ukrytą lambdę w kodzie która imo może prowadzić do paru wtfów w przyszłości

1

Oficjalny bug ktory ktos zglosil do Cassandry: https://issues.apache.org/jira/browse/AAR-7603

1 użytkowników online, w tym zalogowanych: 0, gości: 0, botów: 1

Robot: Applebot