Behind jaggi lines, pt. II
16 May 2005
Pisałem kiedyś w niezbyt przychylnych (a może zbyt nieprzychylnych) słowach o PHP5. Z instalacją nowego systemu pociągnąłem sobie deby z tą wersją interpretera spoza distro. Krótka chwila na wybadanie nowych (nowych dla PHP oczywiście) cech języka pozwoliła nabyć pierwszego wrażenia: nareeeszcieeee. A zaraz potem i drugiego: czemu tylko tyle?. Jednym słowem, krok we właściwym kierunku, ale bardzo mały.
Najpierw to, czego brak wołał o pomstę do nieba: specyfikator static. Obsługa statycznych składowych jest troszkę pokręcona, ale daje się przyzwyczaić. Po prostu trzeba pamiętać, żeby zamiast $this->zmienna stosować self::$zmienna. A minor catastrophy. Wreszcie można stosować porządny singleton zamiast piekielnych sztuczek z serializowaniem zmiennych składowych do sesji i odserializowywaniem ich za każdym wywołaniem konstruktora.
Wyjątki. Nie ma co wiele gadać, potrzebne były.
Iteratory. Fajna rzecz. Gdy tylko w pracy przesiądziemy się na piątkę, natychmiast wyposarzę swoje klasy drzew w ten przyjemny ficzer.
Type hinting, czyli function doSomething(ClassName object). !!! !!! - Tyle mogę tylko powiedzieć. Szkoda, że w tak wąskim zakresie - określać można tylko klasy, skalary i tablice można radośnie mieszać dalej, a wiadomo, że kto miesza ten rzyga. Jest to kolejny kroczek do silnego typowania, lub (co w sumie nawet by mnie zadowoliło) typowania na żądanie.
Poza tym drobnostki, jak zabronienie operacji przypisania do $this w konstruktorze, czy sensowniejsze zachowanie przy rzutowaniu stringów na tablice, metoda __toString. Smaczne, ale zdecydowanie drugoplanowe.
A teraz, gdy już pierwszy głód został zaspokojony pora wysunąć dalsze żądania:
- Dalsze postępy w silnym typowaniu. Od zmiennych składowych po typy zwracane z metod.
- Przeciążanie metod. No comments, jak ostatnio sprawdzałem to mieliśmy XXI wiek.
- ... i operatorów. Jak C++ nie lubię, to nie gniewałbym się z tego zapożyczenia.
- Może pierdoła, ale zwłaszcza gdy nie widać dobrze hierarchii klas przydałoby się obowiązkowe słowo kluczowe
overrideprzy przeciążaniu metod wirtualnych. - Kontener/komponenty sesyjne. Taaa, i co k* jeszcze ;-).
- Jajcus
Oj Pythona, to ty raczej nigdy byś nie polubił. Prawie wszystko z czego się cieszysz, albo czego oczekujesz, to rzeczy za których brak Pythonowcy kochają swój język ;-)
No, przeciążania metod (właściwie tylko konstruktorów) mi trochę w Pythonie brakuje... ale rozumiem czemu tak musi być.- str()
Z tego co mówisz i piszesz, to Python może być ciekawy właśnie przez prezentowanie dość odmiennego od Javy podejścia do programowania. Nie uwiódł mnie gdy próbowałem napisać coś w PyGTK, ale i nie odstraszył. Ma zabawną notację, jeszcze do niego wrócę, może jak przemielę podstawy XUL+Scriptable.
To, o czym mówiłeś dziś, tj. ducktyping (?) całkowicie mnie zadowala. Mogę spokojnie przyjąć dynamiczne typowanie jeśli mam gwarancję, że wszystkie obiekty implementują _nieformalny_ interfejs, którego się od nich oczekuje w danym zadaniu. Niestety w PHP nie jest to realne, bo tu dzieje się wszystko w rantajmie i na sprawdzenie jest zawsze za późno.
A tak poza tym, co złego jest w definiowaniu interfejsu?- Jajcus
Chociażby to, że nigdy nie wiesz jakiego dokładnie będziesz potrzebował. Powiedzmy, że masz obiekt operujący na plikach. Różne jego metody przyjmują jako argumenty pliki. Czyli można by zdefiniować interfejs "IFile", który implementowałby, powiedzmy, metody read(), write(), seek(). W takim przypadku ktoś może w swoim obiekcie, pełniącym rolę pliku, zrealizować interfejs IFile i używać teog obiektu zamiast pliku. Ale po co implementować wszystko, jeżeli obiekt jest tylko czytany? To co, trzy interfejsy? IReadableFile, IWrittableFile, ISeekableFile? Do tego cały zestaw interfejsów pochodnych, jeżeli język nie pozwala na podawanie zestawu interfejsów w sygnaturze metody (np. ReadableFile+ISeekableFile)?
A może zdefiniować zachowanie niezaimplementowanych metod interfejsu IFile? Ale przecież to już ma zdefiniowane interfejs każdego obiektu w Pythonie — wyjątek AttributeError.
Jednak też nieprawdą jest, że w Pythonie zupełnie nie ma interfejsów. Jest kilka implementacji takich mechanizmów, używanych tam, gdzie okazały się konieczne, np. w dużych frameworkach, jak Zope. Wszystko przy wykorzystaniu istniejących, udokumentowanych cech języka.
W świecie Pythona większośc interfejsów jest umownych, ale to działa. Sama rozszerzalność języka oparta jest o takie umowne interfejsy. Jeżeli obiekt ma metody __getitem__() i __contains__() (no, jeszcze kilka dla kompletu), to już może być używany jako słownik. Jeżeli ma metodę __call__(), to jako funkcja, itd. itp. Inna sprawa, że w większości przypadków nie trzeba tego wszystkiego implementować od zera, bo teraz w Pythonie można dziedziczyć po dowolnym wbudowanym typie (łącznie z integerem, funkcją, czy klasą). To po prostu trochę inna filozofia niż w językach ze statyczną kontrolą typu, jak i tych typowo-skryptowych ze słabym typowaniem (bash, tcl, perl, php).







