PHP, ech
Siadłem do napisania poważniejszej rzeczy w PHP. W odróżnieniu od tego co robię w pracy, tu mam do dyspozycji całe PHP5 wreszcie. Potrzebowałem tymczasowo stworzyć obiekt, który kiedyś w przyszłości będzie do Smarty przekazywany i będzie miał wiele zastosowań, na razie do proof of concept była mi potrzebna jedna jego metoda.
Więc sobie pomyślałem - cóż prostszego, stworzę sobie klasę anonimową, ją skonstruuję w Smarty->assign() i będzie dobrze, jedna metoda, co za problem.
$this->CISmarty->assign('user', new class { public function foo() { return false; } };);
Jak się słusznie domyślacie, to tak się nie da. No to pomyślałem, że może da się inaczej. Wewnątrz funkcji stworzyłem klasę o nazwie __anonymous1 i spróbowałem ją utworzyć. Cóż mnie spotkało?
Fatal error: Class declarations may not be nested
Przeniesienie deklaracji mojej klasy "anonimowej" poza klasę w której metodzie potrzebowałem owej klasy anonimowej użyć oczywiście sprawę rozwiązało, jednak zdałem sobie po raz kolejny sprawę, że inne języki programowania (Java, C#) z którymi mam styczność mnie rozbestwiły. Owszem, w tym przypadku klasa anonimowa to tylko "lukier składniowy", luksus, jednak... pewien niesmak pozostaje.
Może w PHP6.5?
Choć tak na serio to najbardziej mi i tak brakuje możliwości zrobienia czegoś w rodzaju $bar = returnMeAnArray()['baz'];
11 października 2008 16:42:27
Może $smarty->assign_by_ref() ?
11 października 2008 17:07:16
assign_by_ref() (który tutaj by się pewnie przydał, zamiast kopiować klasę) nie ma nic do tego, że nie mogę sobie stworzyć klasy „w locie” ani mieć klasy w klasie, a ja na to narzekam.
11 października 2008 18:19:12
Jak nie jak tak to jak nie?
Zależy do czego – zawsze możesz sobie klasę utworzyć eval-em. W C++ też sobie w runtime klasy nie zadeklarujesz raczej.
Swoją drogą, to zamiast:
$this->CISmarty->assign(‘user’, new class { public function foo() { return false; } };);
Nie mogłeś stworzyć sobie zwykłej klasy (nie anonimowej) i jej używać?
11 października 2008 20:02:48
BTM: Tak, mogłem. I tak zrobiłem, stworzyłem klasę zwykłą i jej instancję przekazałem. Ale ja bym chciał anonimową – a tu się nie da.
Użycie klas/funkcji anonimowych jest po prostu w przypadku niektórych rzeczy prostsze (bardziej czytelne) niż tworzenie sobie gdzieś innej klasy, tak samo czasem przydatne są klasy wewnątrz innych klas, czego również PHP nie umożliwia. Nie jest to jakieś wielkie wymaganie, bez tego równie dobrze można się obejść – po prostu zwracam uwagę, że czasem po przejściu z np. Javy do PHP chce się stosować rzeczy, których w PHP nie ma, choć ma się w głowie „ale przecież tak się powinno dać”.
I nie jest to tworzenie klas w runtime – w przypadku choćby C# się to pisze normalnie, a kompilator sobie to sam przerabia. Z mojego new class { ... }; robi się gdzieś w kodzie class __anon1 { ...}; i new __anon1; a potem jest normalnie kompilowane. Żadnego tworzenia czegoś w runtime.
11 października 2008 20:05:23
Wiesz, PHP nie umożliwia wielu rzeczy, które fajnie by było, gdyby umożliwiało (wskaźniki, przeciążanie operatorów czy funkcji, type hinting z jednoczesnym default value dla typów podstawowych [function costam(int a = 5)]) ale niestety nie ma – jakoś musim z tym żyć ;-)
Jeżeli chodzi o przerabianie klas anonimowych na __anon1 – tak, tylko, że PHP jest językiem interpretowanym i tutaj leżymy :-)
11 października 2008 20:09:04
btm: Akurat za wskaźnikami nie tęsknię ;-) Przeciążanie operatorów jest fajne, ale też to jest „lukier składniowy” (i jest rozszerzenie PECL do tego, kiedyś szukałem czy się da jak zechciałem stworzyć obiektowego stringa na wzór C#/Javy). Type hinting ma być w PHP6 (hurra!). Jedna z kilku fajnych nowości, oprócz goto ;-)
11 października 2008 20:56:06
type hinting jest już w 5.2.x, ale działą tylko z typami złożonymi – mam nadzieję, że w 6 z podstawowymi też będzie.
Przeciążanie operatorów głównie potrzebne mi było kiedy robiłem ORM, ale potem i tak stwierdziłem, że to strata czasu. Wskaźniki w sumie na upartego można zastąpić referencją, ale akurat mi się wskaźniki bardziej podobają.
I tak, jak było wyżej zaznaczone najbardziej brakuje mi rozwiązań typu returnArray()[0] etc. znanych chociażby z Javy/C :(