Wiem, że wielu z nas prowadzi własną bibliotekę osobistą z narzędziami i narzędziami, z których często korzystamy.
Miałem swój odkąd miałem 16 lat, więc urósł do całkiem sporych rozmiarów. Niektóre rzeczy, które napisałem, zostały dodane do frameworka. Napisałem własną małą implementację drzewek ekspresyjnych do użycia z algorytmami genetycznymi na długo przed LINQ, co bardzo mi się podobało i z czego byłem dumny - oczywiście teraz jest całkiem bezużyteczne. Ale ostatnio przeszedłem przez to i uaktualniłem do .NET 4.0 i ponownie wzbudziłem zainteresowanie.
Jestem więc ciekawy, do czego używasz swojej biblioteki. Może moglibyśmy znaleźć fajne pomysły na przydatne małe fragmenty i podzielić się nimi między sobą.
Więc moje pytania to:
- Czy masz różne biblioteki narzędzi?
- Z której części jesteś najbardziej dumny i dlaczego?
Podaj przykład kodu, jeśli chcesz :-)
Odpowiedzi:
Nie.
Widziałem koszmarne efekty kilkunastu programistów, którzy dodawali do projektów własne małe biblioteki w stylu „util.h” i zamieniali się w gigantyczny bałagan niespójnych nazw i zachowań funkcji. Podobnie jak PHP. Z tego powodu unikam tego.
Unikam potrzeby robienia tego, używając środowisk programistycznych, które dają mi prawie wszystkie narzędzia i biblioteki, których potrzebuję z góry, gdy tylko jest to możliwe, takie jak C # i python.
źródło
SmartFormat
Moim ulubionym narzędziem jest to, które napisałem - prosty konstruktor / formatator łańcuchów, który naprawdę ułatwia przekształcanie danych w łańcuchy o poprawnej gramatyce.
Na przykład, większość programistów budować tekst z szablonu:
"There are {0} items remaining"
Ale to prowadzi do błędów gramatycznych:"There are 1 items remaining"
.Więc SmartFormat pozwala napisać:
"There {0:is|are} {0} item{0:|s} remaining"
.Wystarczy wymienić
String.Format(...)
zeSmart.Format(...)
i to jest to!SmartFormat kod jest open source: http://github.com/scottrippey/SmartFormat/wiki
źródło
java.text.MessageFormat
.MessageFormat
maChoiceFormat
klasę, która pozwala NAJWYŻSZEJ podobnej składni! Przykład z dokumentacją:"There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}."
. Dziękujemy za wzmiankę o tej referencji."{Count:<0?negative|=5?five|>50&<100?large|other}"
. Ma odbicie (tj."There are {items.Length} items"
Może formatować elementy tablicy i przedziały czasowe. Dodatkowo ma model wtyczki do obsługi jeszcze większej liczby funkcji.Smart.Format("There are {0.Count} files: {0:'{}'|, |, and }.", files);
spowoduje"There are 3 files: 'a.txt', 'b.txt', and 'c.txt'."
. Bez tego nie wyobrażam sobie „lokalizacji”.K Combinator (C #, Scala)
Używam kombinatora K w Ruby dość często, głównie podczas składania, gdy operacja składania jest wykonywana raczej przez efekt uboczny niż przez wartość zwracaną, jak w tym przykładzie:
To liczy, jak często występuje każdy element
some_collection
. Niestety, to tak naprawdę nie działa, ponieważ blok musi zwracać nową wartość akumulatora przy każdej iteracji, ale w przypisaniach Ruby ocenia się na przypisaną wartość.Musisz więc w sposób ekscytujący zwrócić nową wartość akumulatora w następujący sposób:
Ale takie wyraźne sekwencjonowanie wydaje mi się brzydkie w tym funkcjonalnym stylu przy użyciu fałd. Kombinator K (nazywany
Object#tap
w Ruby) na ratunek:Parę razy tęskniłem już w języku C # (głównie z jakiegoś powodu mutatory kolekcji, takie jak
List.Add
returnvoid
zamiast zamiastthis
) i Scala, więc noszę to:oraz w Scali:
Funkcja tożsamości (Ruby)
Coś, czego mi brakuje w Ruby, to przyjemnie nazwany sposób dostępu do funkcji tożsamości. Haskell zapewnia funkcję tożsamości pod nazwą
id
, Scala pod nazwąidentity
. Umożliwia to pisanie kodu takiego jak:Odpowiednikiem w Ruby jest
Czyż nie dokładnie stacza się z języka, prawda?
Poprawka jest
ForEach (.NET)
Kolejna bardzo brakująca metoda w języku C #:
źródło
Action
implikuje skutki uboczne, które są sprzeczne z zasadami projektowania LINQ.IEnumerable
Rozszerzenia zostały dodane dla LINQ.ForEach
nie jest operatorem LINQ. Dlaczego ograniczenia, które dotyczą tylko operatorów LINQ, powinny być stosowaneForEach
, a nie operator LINQ? I dlaczego efekty uboczne są zabronione,IEnumerable.ForEach
ale dozwoloneList.ForEach
? Ponadto, dlaczego efekty uboczne są zabronione,IEnumerable.ForEach
ale dozwoloneforeach
?List<T>
ma,ForEach
jest uzasadniony, biorąc pod uwagę, że jest to typ zmienny.Mam konwerter typów Java. Ma podpis publiczny
i stara się przekonwertować wartość źródłową na typ docelowy. Zasadniczo pozwala to na dynamiczne pisanie w statycznym języku :-)
Jest to przydatne w przypadku pudełkowych typów numerycznych. Jak denerwujące jest to, że nie możesz postawić tego,
Integer
coLong
jest oczekiwane? Nie ma problemu, wystarczy go przekonwertować. A co jeśli twoja funkcja oczekujedouble
, ale musisznull
ją tam umieścić? Kaboom, NPE. Ale przełóż toconvert
, a dostanieszNaN
.źródło
NaN
wsparcie.NaN
jest świetny. Szkoda, że nie ma czegoś takiego dla liczb całkowitych. UżyłemInteger.MIN_VALUE
jako konwencji. Zazwyczaj jest to „dość dziwne”, aby zostać zauważonym, w przeciwieństwie do domyślnej wartości 0. Nie wiem, dlaczego auto (un) boxing nie traktuje się(Double) null
tak jakNaN
. To oczywiste właściwe rozwiązanie, IMHO.Z kodu misc, który napisałem, większość dobrych rzeczy znajduje się teraz w CCAN , a resztę szukam lepszych wersji w istniejących projektach open source. W dzisiejszych czasach piszę coraz mniej ogólnego kodu „misc” na korzyść pisania wariantów takiego kodu specyficznych dla aplikacji lub pisania modułów ogólnego przeznaczenia, które mogę samodzielnie wydać.
do
Oto funkcja i typefef, którego użyłem więcej niż raz. W aplikacjach, które wymagają synchronizacji, trudno jest przekroczyć milisekundy pod względem prostoty:
I więcej różnych funkcji C, których używam w kółko (i więcej):
Haskell
nub :: (Eq a) => [a] -> [a]
Funkcja Haskella to O (n²), ponieważ ze względu na jej podpis typu można testować tylko, czy dwa elementy są równe. Prosta alternatywa O (n log n) jestmap head . group . sort
, ale wymaga wymuszenia całej listy danych wejściowych przed wygenerowaniem danych wyjściowych, podczas gdynub
można od razu zacząć wytwarzać dane wyjściowe. Oto O (n log n) alternatywa dlanub
zbierania już widocznych elementów wData.Set
:W Haskell, używam alternatywy dla
sequence
,mapM
,forM
,replicateM
, ifilterM
. Każda z tych akcji generuje listę, ale listy nie można użyć, dopóki akcja nie zakończy się w całości (jeśli używasz ścisłej monady, takiej jak IO). Alternatywy budują listę w odwrotnej kolejności niż tworząc wieżę grudek, które znalazłem dzięki analizie porównawczej jako szybszej, przynajmniej w przypadku GHC.Uwaga:
sequence_
,mapM_
,forM_
, ireplicateM_
funkcje są jeszcze lepszym wyborem, jeśli nie jesteś zainteresowany w liście wynikowej.źródło
Kończę wdrażanie split / join ala Perl w językach, które go nie mają.
Zaimplementowałem również atoi i itoa w C więcej razy, niż chcę o tym myśleć (śmieci z systemów wbudowanych).
źródło
Nie.
Większość kodowania wykonuję w Javie, a najlepszą praktyką jest ponowne użycie „utils” z bibliotek Apache Commons i podobnych projektów.
Jeśli jesteś tego obiektywny, istnieje kilka przypadków, w których Twoja własna kolekcja „utils” znacząco poprawi to, co zrobili już inni ludzie. A jeśli nie jest to poprawa, to biblioteka utils jest prawdopodobnie stratą czasu na programowanie i stanowi utrapienie dla przyszłych opiekunów.
źródło
Miałem kilka manipulacji datą, które wykonałem przy użyciu Javy, a potem zacząłem używać JodaTime ponieważ słyszałem o nim dobre rzeczy i że powinien zostać włączony do Javy 7 (nie jestem pewien, czy tak jest nadal, ale nawet jeśli tak nie jest, nadal jest warto go używać imho).
Przekształcił klasę linii 50+ w jedną linię z około trzema połączonymi wywołaniami metod.
Dla ciekawskich wymagało to ustalenia daty dla każdego dnia n tygodni wcześniej: np. Wartość sprzedaży w poniedziałek 10 tygodni temu itp.).
A oto część tego
źródło
Zawsze mam jakiś
utils
pakiet, nawet w Javie, ale moja kolekcja narzędzi PHP jest najczęściej używana. W Javie jest tak wiele dobrych bibliotek, że albo mam już bibliotekę zawartą w projekcie, albo muszę po prostu zaprojektować kilka brakujących narzędzi na własną rękę. Biblioteki PHP zwykle robią za dużo, aby móc je włączyć do moich projektów.Podoba mi się ta funkcja dla PHP, dopracowana przy pomocy StackOverflow ...
Jest podobny do BeanUtils dla Javy Apache i używam go do podobnego celu, nadając elementom formularza w języku szablonów pojedynczy klucz, który może uzyskać / ustawić wartość zagnieżdżoną w tablicy źródłowej:
Oczywiście, będąc PHP, chciałem zachować jak najlżejszą metodę, aby nie była tak funkcjonalna jak BeanUtils
;)
źródło
Standardowej bibliotece Scali brakuje niektórych najczęściej używanych funkcji wyższego rzędu.
Dwie takie funkcje, których najczęściej potrzebuję:
źródło
Obecnie nie. Miałem taki, kiedy robiłem C, ale teraz, gdy robię Javę, nie ma już sensu, biorąc pod uwagę wszystkie standardowe dostępne biblioteki lib, a także wszystkie gadżety pochodzące z projektu Apache.
Jedną z przydatnych rzeczy w mojej bibliotece C lib była szybka i brudna implementacja skończonej maszyny stanów, która pozwoliła zdefiniować skończoną maszynę stanów z tylko dwoma łańcuchami i tablicą ciągów. Można go używać do sprawdzania ciągów pod kątem reguł (np. „Musi mieć długość 4..6 znaków, pierwsza litera, cyfry spoczynkowe”), ale dostępność wyrażeń regularnych sprawiła, że stało się to całkowicie bezcelowe.
źródło
Nie mogę teraz pisać interfejsów użytkownika na pulpicie bez dynamicznych okien dialogowych opartych na różnicowym wykonywaniu . To hack, na który natknąłem się około 1985 roku i zaimplementowałem go w różnych językach więcej razy, niż pamiętam.
źródło
Odkryłem, że piszę dużo tego samego kodu w django. Zrób to wspólne, potem to wspólne i wreszcie to wspólne. Zasadniczo pobierz jeden lub więcej elementów z bazy danych lub zapisz wyniki formularza.
Jeśli każda z tych rzeczy występuje tylko raz w widoku, mogę użyć widoków ogólnych django. Niestety, tak naprawdę nie można ich skomponować i musiałem zrobić kilka rzeczy po kolei.
Poszedłem więc i napisałem jeszcze bardziej ogólną bibliotekę widoków, która działała, najpierw budując listę akcji z odpowiednich zestawów zapytań (lub cokolwiek innego), a następnie zawinęłem listę w widok.
Nadal muszę ręcznie napisać kilka poglądów, ale zwykle są one na tyle skomplikowane, że niewiele z nich można wykorzystać. Cała płyta podstawowa po prostu ląduje gdzie indziej, albo widok ogólny, albo jako dekorator widoku (często dekorowany widok ogólny). Zwykle stanowi to około 10% programów obsługi, które piszę, ponieważ niektóre ogólne funkcje obsługi mogą zrobić wszystko inne.
źródło
Tak, ale tylko dla struktur idiomów specyficznych dla domeny (takich jak kontenery specyficzne dla obiektów gry).
Ponieważ są to proste narzędzia użytkowe niż cokolwiek złożonego, nie jestem z niczego dumny. W tej chwili jestem unikalnym użytkownikiem, więc nie ma się czym pochwalić.
źródło
Sortowanie pośrednie w C ++, oparte na STL
sort
i szablonie funktorów.Potrzeba sortowania pośredniego (w którym pożądanym wynikiem były indeksy permutacji , które wynikałyby z sortowania danych, ale nie samych danych sortowanych ) pojawiła się wiele razy w wielu projektach. Zawsze zastanawiałem się, dlaczego STL nie zapewnił dla niego implementacji.
Innym był cykliczny wektor C ++, w którym indeksy dodatnie i ujemne są modulo z rozmiarem wektora (tak, że wszelkie wartości całkowite są poprawnymi indeksami dla wektora).
źródło
Napisałem mały pakiet utils, gdy tworzyłem Java w moim komputerze. Klasa Sci w liceum. Jestem najbardziej dumny z mojego generatora liczb losowych.
Podpory do mojej inspiracji.
źródło