[PHP] Dokumentowanie kodu
O zaletach dobrej dokumentacji nie trzeba się rozpisywać. Każdy z nas (programistów) zapewne nie raz musiał poprawiać kawałek kodu napisany przez kogoś innego lub też nawet przez siebie samego, jednak z czasem zapomnieliśmy już o co chodziło. Często wtedy patrzymy na kawałek kodu, który wygląda np. tak:
$z = hexdec(80000000);
if ($z & $a)
{
$a = ($a>>1);
$a &= (~$z);
$a |= 0x40000000;
$a = ($a>>($b-1));
}
else
{
$a = ($a>>b);
}
I zastanawiamy się co właściwie autor brał - powinien z tym skończyć.
Skoro wszyscy wiemy jak przydatna jest dokumentacja, zastanawia mnie czemu ani na Politechnice (w swoim krótkim czasie), ani na innej uczelni nie mieliśmy przedmiotów, albo chociażby kilku wykładów/ćwiczeń poświęconych na jej tworzenie? Zapewne dlatego teraz tak mało osób stosuje porządną dokumentację.
Swego czasu powstało doskonałe narzędzie/format dla programistów - Javadoc. Przy użyciu odpowiedniego formatowania komentarzy można było kilkoma kliknięciami wygenerować piękną dokumentację dla swojego projektu - mało tego, z czasem co raz więcej IDE zaczęło implementować ten format dokumentacji i używać dynamicznych podpowiedzi (np. Intelisense). Oczywiście powstawały kolejne klony i porty narzędzia - w tym port dla PHP - phpDocumentator. Jak wygląda wygenerowana dokumentacja można przekonać się np. ze samej strony projektu - oczywiście aplikacja umożliwia dowolne modyfikowanie szablonu dokumentu.
Ok, to tyle tytułem wstępu - tym razem nie będę się skupiał na obsłudze samego phpDocumentatora, ale na opisaniu formatu i podstawowych znaczników, na których operuje.
Podstawowe parametry
Javadoc (oraz pochodne) przeszukuje nasze pliki pod kątem formularzy zapisanych w konkretny sposób - mianowicie wyszukuje on wszystkie komentarze blokowe, dla przypomnienia chodzi o:
/** * */
Bloki te mogą znajdować się przed klasami, funkcjami i zmiennymi (wtedy opisują te elementy) lub też na początku pliki (w takim wypadku zwane są "page-level"). Każdy z bloków może zawierać dowolny komentarz tekstowy, wyświetlany w wyjaśnieniu danego elementu - może także zawierać dowolną ilość oraz kombinację specjalnych parametrów pomagających w formatowaniu, osadzaniu dodatkowych treści oraz podpowiadaniu parametrów wejściowych i wyjściowych funkcji
Każdy parametr zapisuje się poprzedzając go znakiem @, np:
/**
* Poniższa funkcja robi ...
* @PARAMETR WARTOŚĆ PARAMETRU
*/
function foo() { (...) }
Poniżej wymienię najczęściej stosowane parametry, po pełny spis odsyłam do dokumentacji phpDocumentatora. Pragnę zwrócić także uwagę, że niektóre parametry (@abstract, @final) stały się zbędne, ponieważ z wprowadzeniem PHP5 można używać specjalnych słów kluczowych, które do tej pory zastępowały właśnie w/w parametry.
@author - parametr opisujący autora danego fragmentu kodu lub osobę, która ów kod modyfikowała, przyjmuje następującą postać:
* @author Bartosz Szczeciński <btm@anfo.pl>
@deprecated - opisuje element, który znajduje się w kodzie ze wzg. na kompatybilność wsteczną - zaleca się stosowanie nowszego odpowiednika:
* @deprecated Stara funkcja, sugeruję używać nowej wersji
@see - odniesienie do innego fragmentu kodu, np. w połączeniu z @depracated może wskazać funkcję, którą powinniśmy używać zamiast poprzedniej:
* @see innaKlasa::innaFunkcja
@example - po parametrze należy podać ścieżkę do pliku zawierającego przykład zastosowania danego kawałku kodu:
* @example przyklady/userApiTest.php
@link - podobnie jak @see, jednak odnosi nas do podanego adresu URL
* @link http://manual.phpdoc.org/HTMLframesConverter/default/
@param - jeden z najczęściej wykorzystywanych znaczników, określa typ i rolę parametru, jaki powinniśmy przekazać do funkcji. Ponieważ PHP nie posiada na razie obsługi deklaracji typów złożonych w funkcjach jako pierwszą wartość parametru podajemy jego typ
/**
* @param int $foo określa zasadę działania funkcji
* @param int|string $bar dodatkowy parametr, powinien to być int lub string
*/
function testFunction($foo, $bar) {(...)}
@return - kolejny z najczęściej wykorzystywanych parametrów - podobnie jak @param określa typ zwracanej przez funkcję wartości. Ponieważ funkcje zwracają tylko jedną (i to nie nazwaną) wartość, jego użycie jest dużo prostsze:
/**
* @return int zwraca losową wartość, uzyskaną przez rzut kostką 1K6
*/
function random() {
return 4;
}
@todo - parametr informujący nas, że podany fragment kodu jest niekompletny lub wymaga poprawek, niektóre programy IDE pozwalają nam na szybkie wyświetlenie wszystkich fragmentów kodu oznaczonych tym parametrem, więc od razu wiemy co jeszcze musimy poprawić
* @todo funckja random() powinna losować wartość za każdym razem
@var - tak, jak przy pomocy @param mogliśmy określić typ i zastosowanie parametru wejściowego wybranej funkcji, za pomocą @var możemy określić zmienne umieszczone w kodzie. Wszelkie zmienna nie opisane tym parametrem i nie posiadające odpowiedniej deklaracji zostaną opisane jako mixed
/** * @var int totalnie losowa liczba, serio */ $random = 4;
Podsumowanie
Jak już wspomniałem na wstępie - standard phpDoc definiuje jeszcze wiele dodatkowych parametrów pozwalających na lepszą organizację naszego kodu, jednak poznanie i stosowanie chociażby tej garstki podstawowych z nich pozwali nam (i naszym współpracownikom) na dużo łatwiejsze i wygodniejsze poruszanie się po kodzie - a wygenerowana z naszego kodu dokumentacja zaoszczędzi nam wielu godzin spędzonych na szukaniu odpowiednich fragmentów kodu czy też tłumaczeniu i odgadywaniu zasad działania kawałku oprogramowania, za który właśnie staliśmy się odpowiedzialni.
Za jakiś czas postaram się opisać jak skonfigurować phpDocumentator w celu wygenerowania dokumentacji z naszego projektu.
Komentarze
Komentarz użytkownika Wasacz
01 07 2010Doxygen jeszcze ;)
Komentarz użytkownika BTM
01 07 2010Dzięki za cynk - zdaje się być częściej aktualizowany niż phpDocumentator ;-)
Komentarz użytkownika Wasacz
01 07 2010A proszę ;)
Komentarz użytkownika dikamilo
01 07 2010Sphinx jeszcze ale chyba tylko dla pythona.
Komentarz użytkownika SebaS86
01 07 2010Patrząc na przykładowy kawałek kodu nie wiem czy dokumentacja w czymkolwiek pomoże. :P
Komentarz użytkownika BTM
01 07 2010@SebaS86: przynajmniej będzie wiadomo, co robi (function zeroFill($a, $b))
Komentarz użytkownika dreame4
02 07 2010Dobrze zebrane w całość, na pewno się przyda ;)
Komentarz użytkownika lolek
02 07 2010Czy jakieś GUI do Pythona potrafi wykorzystywać informacje wyciągniete z *doca(np. @return) do podpowiadania składni, tak jak dzieje się to w przypadku PHP w Netbeans/Eclipse?