Autoboxing?

15
maj/10
15

Każdy wie jak fantastycznie korzysta się z dobrze zaprojektowanych interfejsów klas. Z narzędzi i modeli, których logicznie zbudowane metody i atrybuty pozwalają na programowanie w sposób, w jaki traktujemy obiekty ze świata rzeczywistego. To są zupełne aksjomaty, nie ma o czym dyskutować. Jeśli chodzi o PHP, to największą bolączką jego OOP jest paradoksalnie jego brak. Może inaczej. Niekonsekwencja w stosowaniu tego paradygmatu. Mamy typy prymitywne, przykładowo „string” oraz możliwość budowania klas, które mogą być rzutowane na ten typ. Wykorzystujemy albo typ prymitywny albo klasę; jedno albo drugie. Na dodatek rzutowanie istnieje tylko dla typów „string” i tablic. To wszystko wygląda jak klejone na poczekaniu, bez większego pomyślunku rozwiązanie. Mały bałagan, ale to może się niedługo zmienić.

Mam w nawyku co jakiś czas sprawdzać dział RFC na wiki php.net i dziś znalazłem tam nowy, ciekawy szkic propozycji: „autoboxing”. Mówiłem przed chwilą o rzutowaniu, które pozwala skonwertować obiekt na typ prymitywny. Autor propozycji wskazuje pomysł na uzupełnienie funkcjonalności: umożliwienie przejścia z typu prymitywnego na obiekt. Jakie to ma zastosowanie?

$lista = array( 1, 2, 3 );
echo $lista->implode(', ');

Wygląda nieźle prawda? Rozwiązanie działa w nader prosty sposób. W momencie, gdy będziemy chcieli skorzystać z typu prymitywnego w kontekście obiektowym zostanie wywołana zadeklarowana wcześniej funkcja, która zwróci nam obiekt reprezentujący ten typ i jego wartość. Oryginalna propozycja zakłada dość prymitywne deklarowanie funkcji dokonującej transformacji:

function __autoboxing( $value ) {
  if( is_array($value) ) {
    return new MyArrayObject( $value );
  }
}

Jak pisałem wcześniej ta funkcja miała by być wywoływana za każdym razem, gdy próbujemy dostać się do jakiejś metody typu prymitywnego. Funkcja „automagicznie”, zależnie od typu, zwróci nam obiekt odpowiadający typowi. Dzięki temu możemy deklarować zmienne o typach prostych i operować na nich jak na obiektach, zależnie od potrzeby. Świetna sprawa.

Jest jednak sporo problemów. Pomijam fakt, że tworzenie jednej magicznej funkcji działającej w obrębie całej aplikacji nie sprawdziło się już przy funkcjonalności „autoload”. Należy dać twórcom bibliotek możliwość definiowania swoich różnych funkcji dokonujących transformacji, działających jednocześnie. Trzeba w pewnym stopniu zunifikować zwracane abstrakcje typów prymitywnych, wyobraźcie sobie taki przykład:

$lista = array( 1, 2, 3 );
echo $lista->len(); // w jednej bibliotece
echo $lista->length(); // w drugiej bibliotece
echo $lista->getLength(); // w kolejnej bibliotece

Kompletny horror. Podstawowe operacje na typach prostych są już w bibliotece standardowej w PHP i nie wyobrażam sobie by każdy twórca biblioteki nazywał je w inny sposób. Trzeba wykorzystać okazję i zunifikować bałagan nazewnictwa. Więcej, nie wprowadzać jeszcze większego chaosu. Wolność programistów jest ważna, ale pewne konwencje muszą być wymuszone.

Należy stworzyć rejestr funkcji transformujących, zależnych od przestrzeni nazw i typu jaki ma być zwrócony:

spl_autoboxing_register(
  SPL_AUTOBOXING::INTEGER,
  '\My\Library',
  function( $value ) {
    // i tu jakiś: return new MyInteger;
  }
);

Funkcja musi wymuszać pewien interfejs o nazwie w stylu „SplIntegerObject”:

interface ISplIntegerObject {
  public function divide( $value );
  // itd.
}

Myślę, że ważne jest także by funkcjonalność „autoboxing” była dostępna domyślnie z wykorzystaniem przygotowanych przez twórcom PHP klas. W przeciwieństwie do „autoload”, tutaj da się przedstawić standardową implementację na którą zgodzą się wszyscy bez zbędnego narzekania.

Pod propozycją podpisuję się rękoma i nogami o ile zostanie dłużej przemyślana i poprawiona. Jako ciekawostka, jeśli wejdzie w życie w tej czy innej postaci, PHP nie będzie mógł sobie przypisać i opatentować pomysłu. „Autoboxing” funkcjonuje w Java od wersji 1.5.

Opublikowane jako: PHP
Komentarze (15) Odniesienia (0)
  1. sokzzuka
    22:16 on Maj 15th, 2010

    Sam mechanizm jest dość kontrowersyjny i na liście internals (core dev-ów php) było dużo uwag za i przeciw.
    Jest już patch, który każdy może sobie wkompilować do swojego php i przetestować tą funkcjonalność.
    Sam nie wiem czy najlepszym rozwiązaniem nie było by po prostu tak jak w Javie stworzenie klas dla podstawowych typów i możliwość używania ich wg kontekstu. Tzn np dodajemy dwie liczby, operacja jest robiona na typach prymitywnych, ale na wyniku np wykonujemy sobie jakieś metody a konwersja z prymitywnego integera na klase IntegerObject robiona jest niejawnie.

  2. Damian Tylczyński
    08:50 on Maj 16th, 2010

    Twórcy PHP chcą dać programistom za dużo wolności i zapominają, że proste rozwiązania są często najlepsze. Jestem ciekaw jak to wszystko się potoczy.

  3. sokzzuka
    12:00 on Maj 16th, 2010

    Nie powiedziałbym, że to twórcy. Jest to propozycja zgłoszona przez jedną osobę. Natomiast powiedziałbym, że większość core developerów php jest raczej konserwatywna w wprowadzaniu nowości. Są bardzo ostrożni, a w szczególności, jeżeli chodzi o wsteczną kompatybilność.

    Jak dla mnie feature sam w sobie jest ok, (jeżeli nie ma alternatywnych propozycji). Powinien jednak być tylko możliwy do wykorzystania w przestrzeniach nazw, żeby nie mieszać za wiele.

  4. Damian Tylczyński
    12:09 on Maj 16th, 2010

    Tak, z tymi twórcami się trochę zagalopowałem. Nota bene ta wsteczna kompatybilność strasznie ciąży PHP. Na przykład przenieśli by wszystkie funkcje do przestrzeni nazw PHP, porządkując je i pozostawiając tylko interfejsy obiektowe tam gdzie tylko można. Byłoby po krzyku.

    Możliwość tworzenia własnych klas tylko w przestrzeniach nazw, zgadzam się. Przydało by się także wymuszenie interfejsów (dziedziczenia klas?) i przygotowanie domyślnych klas działających także w przestrzeni globalnej by wszystko wszędzie działało tak samo.

  5. anonim :)
    14:11 on Maj 16th, 2010

    Hey,
    mam pytanie , od jakiej wersji php ten autoboxing działa?
    Nigdzie o tym nie napisałeś a i w podanych linkach nie namierzyłem takowej informacji…

  6. Damian Tylczyński
    17:25 on Maj 16th, 2010

    Jest to propozycja funkcjonalności. Niestety nikt nie może przewidzieć na tym etapie w jakiej wersji PHP mogli by ją wprowadzić w życie i czy w ogóle.

  7. sokzzuka
    22:20 on Maj 16th, 2010

    Tu jest link do patcha: http://gist.github.com/162517 trzeba go sobie wkompilowac do php i można się bawić ( o ile ktoś wie jak to zrobić ).
    Co do wstecznej kompatybilności to ma to swoje plusy i minusy, w końcu wszyscy pamietają jakie bęcki dostał microsoft jak zerwał wsteczną kompatybilność wypuszczając Vistę ;)

  8. cojack
    08:27 on Maj 20th, 2010

    Nie no proszę Cię Damian, przecież to jest kolejne gówno w php, niejawne rzutowanie można już robić od początku php, jeszcze jak sobie utworzymy niejawne tworzenie obiektów to już w ogóle będzie można po kodzie php z fulltextsearchem zapierdalać by coś znaleźć i się dowiedzieć SKĄD TO KURWA JEST?

  9. Damian Tylczyński
    08:51 on Maj 20th, 2010

    @cojack, gratuluję przenikliwości. Jako spojler zdradzę Ci, że nie jesteś pierwszą osobą, która zauważyła problem.

  10. sokzzuka
    23:33 on Maj 22nd, 2010

    z tym szukaniem, to jednak w sumie, jeżeli autoboxing działał by tylko dla jakiegoś namespace-a, to tylko w tym namespace miałbyś efekty jego działania, robisz sobię własną bibliotekę masz swój arrayowy obiekt, intowy etc i tam sobie to wykorzystujesz, żaden inny kod tego nie widzi…

  11. Nadja
    00:33 on Maj 23rd, 2010

    Powodzenia dziś!

  12. Damian Tylczyński
    15:14 on Maj 23rd, 2010

    @Nadja, dziękuję bardzo :) PHPCon 2010 skończył się dziś o godz. 13 i muszę przyznać, że była to fantastyczna impreza. Świetni ludzie, różnorodna agenda i fantastyczna atmosfera w kuluarach w luźnych rozmowach przy zimnym piwku. Ci developerzy którzy nie byli mają naprawdę czego żałować! :) Czekam z niecierpliwością na kolejną edycję.

  13. Owen Moskalik
    22:33 on Czerwiec 2nd, 2010

    Sam mechanizm jest dość kontrowersyjny i na liście internals (core dev-ów php) było dużo uwag za i przeciw.Jest już patch, który każdy może sobie wkompilować do swojego php i przetestować tą funkcjonalność.Sam nie wiem czy najlepszym rozwiązaniem nie było by po prostu tak jak w Javie stworzenie klas dla podstawowych typów i możliwość używania ich wg kontekstu. Tzn np dodajemy dwie liczby, operacja jest robiona na typach prymitywnych, ale na wyniku np wykonujemy sobie jakieś metody a konwersja z prymitywnego integera na klase IntegerObject robiona jest niejawnie.
    +1

  14. poweruser
    13:14 on Listopad 10th, 2010

    Na phpclasses jest już pierwsza implementacja autoboxingu z użyciem czystego PHP (a nie modułów do niego)

    http://www.phpclasses.org/package/6570-PHP-Wrap-string-and-integer-values-in-objects.html

  15. poweruser
    09:47 on Kwiecień 14th, 2011

Niestety, skomentowanie tego wpisu jest niemożliwe.

No trackbacks yet.

Optimization WordPress Plugins & Solutions by W3 EDGE