konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Tomasz N.:
Dziedziczenie nie powinno przykrywać zmiennych i funkcji statycznych (nie mamy obiektu, więc tak na prawdę nie wiemy na rzecz jakiej klasy wywołujemy metodę statyczną), dlatego w podanej sytuacji zawsze będzie zwracana wartość z Parent (bo tam jest wywoływana metoda statyczna). Tak jest w innych obiektowych językach programowania (np. Java) i wydaje się to logiczne.

Jak najbardziej sie z Toba zgodze.

Kilka lat temu spotkalem sie z tematem opisanym przez autora watku i po dluzszym zastanowieniu uznalem, ze zle zastosowalem praktyke. Zamiast statycznie powinienem wtedy byl programowac obiektowo.

Statyczne programowanie poza kilkoma wyjatkami (wzorce,tricki wspierajace obiektowosc), sluzy jedynie do organizacji modulowej/bibliotecznej funkcji/metod.

A sila OO tkwi w czystej obiektowosci.

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Dziedziczenie nie powinno przykrywać zmiennych i funkcji statycznych
(nie mamy obiektu, więc tak na prawdę nie wiemy na rzecz jakiej klasy wywołujemy metodę statyczną),

...tyle że tak naprawdę wiemy, na rzecz jakiej klasy uruchamuamy funkcję (bo jest napisane MyChildClass::method()). Może, w C++ to jest inaczej, lecz od języka dynamicznego oczekuje się co innego. To, że Java i C# mają na to inny pogląd, tutaj nie jest relewantne.

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Tomasz Grzechowski:
A sila OO tkwi w czystej obiektowosci.

Czysta objektowość jest okej, jeżeli klasy sami są obiektami (first class objects). I właśnie wtedy opisany przeze mnie problem nie istnieje (statyczne metody są metodami klasy, a nie obiektów tej klasy). Jeżeli mówi się, że obiekt to jedno, a klasa jest zrealizowana poprzez coś innego i jest w terminach języka czymś odrębnym, to nie jest to czysta obiektowość.
Tomasz Niewolik

Tomasz Niewolik
Programista/Projekta
nt

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:
Dziedziczenie nie powinno przykrywać zmiennych i funkcji statycznych
(nie mamy obiektu, więc tak na prawdę nie wiemy na rzecz jakiej klasy wywołujemy metodę statyczną),

...tyle że tak naprawdę wiemy, na rzecz jakiej klasy uruchamuamy funkcję (bo jest napisane MyChildClass::method()). Może, w C++ to jest inaczej, lecz od języka dynamicznego oczekuje się co innego. To, że Java i C# mają na to inny pogląd, tutaj nie jest relewantne.

No nie do końca. Po pierwsze, C++, Java i C# są wyznacznikami dla innych języków jak działa obiektowość (chociaż usprawnienia są zawsze mile widziane). Po drugie, działanie jakiego oczekujesz od metod statycznych zupełnie nie pasuje do koncepcji ich powstania. Metody i zmienne statyczne są po to, by niepotrzebnie nie zajmować miejsca w pamięci i uporządkować kod. Dlatego są tworzone tylko raz i każde wywołanie zawsze uruchamia jedną i tą samą metodę. Dlatego wywołanie MyChildClass::munchName() i MyParentClass.munchName() zawsze powinno zwrócić ten sam wynik, czyli MyParentClass.munchName();. Każde inny wynik byłby nielogiczny, bo oznaczałby, że istnieje wiele instancji metody statycznej.
Tomasz Niewolik

Tomasz Niewolik
Programista/Projekta
nt

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:

Czysta objektowość jest okej, jeżeli klasy sami są obiektami (first class objects). I właśnie wtedy opisany przeze mnie problem nie istnieje (statyczne metody są metodami klasy, a nie obiektów tej klasy). Jeżeli mówi się, że obiekt to jedno, a klasa jest zrealizowana poprzez coś innego i jest w terminach języka czymś odrębnym, to nie jest to czysta obiektowość.

Mógłbyś to szerzej wytłumaczyć, bo nie jestem pewny, czy wiem o co Ci chodzi? W Java klasa jest również obiektem typu Class, co zupełnie nie ma wpływu na działanie metod statycznych, bo i dla czego miałoby mieć?!

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:
Tomasz Grzechowski:
A sila OO tkwi w czystej obiektowosci.

Czysta objektowość jest okej, jeżeli klasy sami są obiektami (first class objects). I właśnie wtedy opisany przeze mnie problem nie istnieje (statyczne metody są metodami klasy, a nie obiektów tej klasy). Jeżeli mówi się, że obiekt to jedno, a klasa jest zrealizowana poprzez coś innego i jest w terminach języka czymś odrębnym, to nie jest to czysta obiektowość.

Chodzilo mi o unikanie programowania statycznego a nie o konstrukcje jezyka.
Bartłomiej Ogryczak

Bartłomiej Ogryczak Backend Developer @
Layar

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:
Dobra. Takie pytanie, które aktualnie stabilne (podkreślam, STABILNE) enterprajzowe distro Unix/Linux, stosowane na serwerach, jest wyposażone w PHP 5.3?

Np. Ubuntu 10.04 LTS Server Edition.

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Tomasz N.:
No nie do końca. Po pierwsze, C++, Java i C# są wyznacznikami dla innych języków jak działa obiektowość (chociaż usprawnienia są zawsze mile widziane).

A nie Smalltalk chyba?
Po drugie, działanie jakiego oczekujesz od metod statycznych zupełnie nie pasuje do koncepcji ich powstania. Metody i zmienne statyczne są po to, by niepotrzebnie nie zajmować miejsca w pamięci i uporządkować kod. Dlatego są tworzone tylko raz i każde wywołanie zawsze uruchamia jedną i tą samą metodę.

Zmienna statyczna ma zaletę co do oszczędzania pamięci, że jest wskaźnikiem na tą samą komórkę pamięci dla wszystkich instancji klasy; taką zaletę mają wszystkie metody, wirtualne czy nie: nigdy nie replikują się w odziedziczonych klasach i instancjach, jeżeli nie przeciężasz ich w swojej klasie.
Dlatego wywołanie MyChildClass::munchName() i MyParentClass.munchName() zawsze powinno zwrócić ten sam wynik, czyli MyParentClass.munchName();. Każde inny wynik byłby nielogiczny, bo oznaczałby, że istnieje wiele instancji metody statycznej.

Nieprawda. Instancja metody jest jedna, lecz niewidzialnie przekazywany argument jest inny (albo, well, musiałby być inny) — $this w przypadku obiektu, i self w przypadku statcznego wywołania. Według logiki, po prostu nie ma sensu pisać myChildClass::blabla(), lecz wyłącznie myParentClass::blabla(), o ile kontekst bierze się jedynie z myParentClass.
Tomasz Niewolik

Tomasz Niewolik
Programista/Projekta
nt

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:
Tomasz N.:
No nie do końca. Po pierwsze, C++, Java i C# są wyznacznikami dla innych języków jak działa obiektowość (chociaż usprawnienia są zawsze mile widziane).

A nie Smalltalk chyba?

Obecnie raczej nie.
Po drugie, działanie jakiego oczekujesz od metod statycznych zupełnie nie pasuje do koncepcji ich powstania. Metody i zmienne statyczne są po to, by niepotrzebnie nie zajmować miejsca w pamięci i uporządkować kod. Dlatego są tworzone tylko raz i każde wywołanie zawsze uruchamia jedną i tą samą metodę.

Zmienna statyczna ma zaletę co do oszczędzania pamięci, że jest wskaźnikiem na tą samą komórkę pamięci dla wszystkich instancji klasy; taką zaletę mają wszystkie metody, wirtualne czy nie: nigdy nie replikują się w odziedziczonych klasach i instancjach, jeżeli nie przeciężasz ich w swojej klasie.

W instancjach zawsze replikują się zmienne, które nie są statyczne (zostańmy przy podziale na statyczne i niestatyczne). W przypadku metod, różnica między zwykłymi i statycznymi dotyczy kontekstu ich uruchomienia. Metody zwykłe są uruchamiane na rzecz konkretnego obiektu (child), a metody statyczne uruchamiane są dla klasy która ją definiuje (a nie dziedziczy!) właśnie dlatego, że jest statyczna!
Dlatego wywołanie MyChildClass::munchName() i MyParentClass.munchName() zawsze powinno zwrócić ten sam wynik, czyli MyParentClass.munchName();. Każde inny wynik byłby nielogiczny, bo oznaczałby, że istnieje wiele instancji metody statycznej.

Nieprawda. Instancja metody jest jedna, lecz niewidzialnie przekazywany argument jest inny (albo, well, musiałby być inny) — $this w przypadku obiektu, i self w przypadku statcznego wywołania. Według logiki, po prostu nie ma sensu pisać myChildClass::blabla(), lecz wyłącznie myParentClass::blabla(), o ile kontekst bierze się jedynie z myParentClass.

I z ostatnim zdaniem się zgadzam - myChildClass::blabla() wprowadza tylko niepotrzebne zamieszaniem skoro uruchamiasz myParentClass::blabla().

Jak sam zauważyłeś zmienna statyczna zawiera wskaźnik do miejsca w pamięci, gdzie jest wartość, a nie odwołuje się bezpośrednio przez wartość dlatego pobiera nazwę klasy Parent, a nie Child (w metodzie myParentClass::blabla() wskaźnik wskazuję na nazwę myParentClass niezależnie od dziedziczenia). Skoro w klasie myChildClass nie zasłaniasz metody blabla() to znaczy, że uruchamiasz jej wersję z myParentClass, a skoro tamta metoda jest statyczna to nie może pobrać nazwy klasy z myChildClass tylko pobiera z miejsca na które wskazuje jej wskaźnik, czyli z myParentClass. Gdyby metoda nie była statyczna to nazwa byłaby pobierana z $this i wskazałaby na myChildClass. Prościej chyba się już nie da tego wytłumaczyć. ;-)

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Mówisz o tym tak, jakby to było coś dobrego.

Z drugiej strony, niejaki kontekst jednak _jest_ przekazywany — w PHP nazywa się on "self". Problem polegał (do PHP 5.3) na tym, że dla nie wiem jakiego powodu w języku dynamicznym statyczne wiązanie było statyczne.

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Ilustracja: w Pythonie każdej metodzie przekazywany jest wskaźnik na kontekst (self). W przypadku obiektu jest to obiekt, w przypadku klasy jest to sama klasa. Dlatego występuje różnica pomiędzy A.foo() i B.foo(), również można nawet zrobić różnicę pomiędzy A.foo() i A().foo(). W PHP to pierwsze jest dostępne przez LSB, z problemami (np. http://bugs.php.net/bug.php?id=43408) i tylko z wersji 5.3 (bo naprawić get_class() to bardzo skomplikowane, prościej jest wrzucić jeszcze jedną... dwie... więcej! funkcji do globalnej przestrzeni nazw), drugie realizuje się poprzez isset($this).

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Zabawkowa wydajność? Zabawkowa prostota?
To dzięki tym dwóm czynnikom największe portale wciąż używają tego języka.
Jarosław Fedewicz:
Niekiedy się zdarza, że jakaś metoda musi wiedzieć, jak nazywa się jej klasa. Napr., ORM może z nazwy klasy wygenerować nazwę tablicy lub coś jeszcze takiego. I wszystko jest okej do pory, gdy chcemy dowiedzieć się nazwę klasy w kontekście statycznym. To znaczy:


<?php [/quote]> class MyParentClass { [quote] public static function munchName() {
return strtolower(get_class()); // myparentclass
}
}

class MyChildClass extends MyParentClass {
}

echo MyChildClass::munchName(); // myparentclass... WTF?!


Więcej tego, gdy próbujesz jakoś to obejść przy pomocy get_class(new self()), to wszystko jedno nic nie wyjdzie, ponieważ metoda statyczna jest odpalana w kontekście klasy, w której ją zadeklarowano.

No i na deser. O tej przykrości jest bugreport, jednakże na nim padła rezolucja, że nie będą nic tam poprawiać, bo to okazuje się zbyt skomplikowane...

No i traktuj po czymś takim (a takich błędów architekturalnych mają dużo więcej) PHP poważnie. Zabawkowy język, zabawkowe OOP, zabawkowy dynamizm.Jarosław Fedewicz edytował(a) ten post dnia 23.06.10 o godzinie 13:40
Tomasz Niewolik

Tomasz Niewolik
Programista/Projekta
nt

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:
Mówisz o tym tak, jakby to było coś dobrego.

Z drugiej strony, niejaki kontekst jednak _jest_ przekazywany — w PHP nazywa się on "self". Problem polegał (do PHP 5.3) na tym, że dla nie wiem jakiego powodu w języku dynamicznym statyczne wiązanie było statyczne.

Bo to jest dobre i logiczne! To, że język jest dynamiczny nie powinno oznaczać, że nie panują w nim żadne reguły. Skoro sam tworzysz wiązanie statyczne (static nie jest opcją domyślną, zatem tworzysz zmienną lub metodę statyczną świadomie) to znaczy, że chcesz takie właśnie wiązanie. Jeżeli dobrze zrozumiałem czego oczekujesz od static to po prostu chodzi Ci o Singleton...

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Nie. Mi nie chodzi o singleton, lecz o taką metodę, która jest w stanie skalkulować jakąś wartość opierając się na nazwie klasy, z której ją wywołano, ale bez konieczności tworzenia jeszcze jednej instancji. Może występować jako alternatywny konstruktor, jak naprzykład DatabaseRecord::retrieveByPK() (chyba są powody do tego, by konstruktor takiej funkcji nie posiadał sam w sobie). Nie chcę mieć kodu generowanego (jak to robi Propel), ani zasłaniać metodę w każdej klasie dziedziczonej.

Teraz obchodzę problem przy pomocy
$x = new Entity();
$x = $x->retrieveByPK($y);

ale to nie jest idealne rozwiązanie.Jarosław Fedewicz edytował(a) ten post dnia 25.06.10 o godzinie 15:46

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Wojtek A.:
Zabawkowa wydajność? Zabawkowa prostota?
To dzięki tym dwóm czynnikom największe portale wciąż używają tego języka.

Wrong. Używają go, bo

1) ma bardzo niski próg wejściowy (w porównaniu do Perl, który był używany niemal we wszystkich największych portalach aż do rozpowszechnienia PHP4) i

2) pozwala zatrudniać tańszą siłę roboczą z powodu swojej specjalizacji (w przeciwieństwie, ani Pythona, ani Javy, ani C++ nie używa się wyłacznie albo prawie wyłącznie do webu, i zazwyczaj specjaliści mają duże doświadczenie poza webem — dlatego kosztują).
Piotr Jasiulewicz

Piotr Jasiulewicz PHP/Java
professional

Temat: Jeszcze jeden powód, z którego PHP sucks

Jeśli nie chcesz tworzyć obiektów, nie chcesz używać singletona (pomimo, że to by tu najbardziej podchodziło), chcesz, żeby metody statyczne działały jak ewidentnie w żadnym języku nie działają... to ja polecam:

function returnByPk($Nazwa) ;-)

1) nie tworzy obiektu
2) globalnie dostępne
3) nie jest singletonem

Ew. można też napisać następny język programowania, który będzie logiczniejszy niż wszystkie inne :)

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Już jest. Przykłady są wyżej.
Tomasz Niewolik

Tomasz Niewolik
Programista/Projekta
nt

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:
Nie. Mi nie chodzi o singleton, lecz o taką metodę, która jest w stanie skalkulować jakąś wartość opierając się na nazwie klasy, z której ją wywołano, ale bez konieczności tworzenia jeszcze jednej instancji.

Ale to byłoby zaprzeczeniem dziedziczenia! Jeśli masz dziedziczenie to i tak wpierw jest tworzony Parent, a potem Child (pomijam już specyfikę static)! Chciałbyś mieć potomka bez rodzica?

konto usunięte

Temat: Jeszcze jeden powód, z którego PHP sucks

Jaką stroną normalne LSB zaprzecza dziedziczenie? Does not compute...
Tomasz Niewolik

Tomasz Niewolik
Programista/Projekta
nt

Temat: Jeszcze jeden powód, z którego PHP sucks

Jarosław Fedewicz:
Jaką stroną normalne LSB zaprzecza dziedziczenie? Does not compute...

Chęć stworzenia obiektu/klasy child bez tworzenia obiektu/klasy parent jest zaprzeczeniem dziedziczenia.



Wyślij zaproszenie do