Na prośbę empathon'a zakładam niniejszy temat
Czegos takiego nie ma
Zapraszam na http://www.ruby-lang.org
http://pl.wikipedia.org/wiki/Metaprogramowanie
"Metaprogramowanie może polegać nie tylko na generowaniu kodu, ale również na modyfikacjach w czasie wykonania programu. Takie możliwości dają języki LISP, Smalltalk, PHP, Python, Ruby oraz Perl."
http://en.wikipedia.org/wiki/Metaprogramming
"Not all metaprogramming involves generative programming. If programs are modifiable at runtime (such as in Lisp, Python, REBOL, Smalltalk, Ruby, PHP, Perl, Tcl, Lua, and JavaScript), then techniques can be used to perform metaprogramming without actually generating source code."
Tzn. ze uwazasz
<?php $class_name = 'Article'; $article = new $article; ?>
@LoPMX - nie, to jest wykorzystanie możliwości składni języka w służbie polimorfizmu
metaprogramowanie natomiast... http://pl2.php.net/manual/pl/ref.classkit.php
Pozdrawiam
@ Cysiaczek : Ale po co podsylasz oczywiste linki?
Prawda jest taka, ze jest to czyste naciaganie, by nadarzac za trendem.
PHP od srodka jest kiepskim jezykiem, balaganiarskim. Ale skoro uwazasz, ze chcesz uzywac tak ubogiego i malo elastycznego API to... powodzenia.
W PHP można bardzo dobrze symulować metaprogramowanie.
http://interfacelab.com/metadataattributes-in-php/ Nie sa to możliwości Javy ale też coś.
Jakiś czas temu pisałem o http://blog.dywicki.pl/2008/01/20/adnotacje-w-javie-i-w-php/. Jest to nieco wygodniejsze niż http://interfacelab.com/metadataattributes-in-php/. Można na podstawie tego narzędzia napisać kolejny generator ale nie będzie też problemu żeby wykorzystywać adnotacje w czasie działania (Reflection API).
LoPMX propagandy na rzecz Ruby nie potrzebujemy, jest dosyć tego śmiecia w Internecie.
a ja sie zgadzam z LoPMX (nie tylko w tym, ze PHP jest nieuporzadkowane - lekkie stwierdzenie - ale tez, ze w PHP metaprgramowania nie ma). i nie robie zadnej propagandy na rzecz innych jezykow, bo pisze glownie wlasnie w PHP , a juz na pewno nie na rzecz Ruby, bo nigdy go nie uzywalem (jeszcze).
przynajmniej w samym PHP. chyba, ze by podciagnac pod to http://www.php.net/eval. oczywiscie jest rozszerzenie classkit (ale jest to stare rozwiazanie, znacznie bardziej rozwiniete jest http://www.php.net/manual/pl/book.runkit.php) wspomniane przez Cysiaczka, no ale rownie dobrze mozna powiedziec, ze PHP umozliwia przeciazanie operatorow, bo jest rozszerzenie http://pecl.php.net/package/operator.
natomiast co do adnotacji, czy ReflectionAPI to nie do konca jest to zgodne z definicja metaprogramowania. poniewaz to nie generuje zadnego kodu, pozwala jedynie odczytywac informacje o juz istniejacym. ReflectionAPI to nic wiecej jak reverse engineering.
aczkolwiek zastanawiajaca mogla by byc taka technika:
<?php $id = http://www.php.net/uniqid(); $content = '<?php /* tutaj kod wygenerowany na podstawie jakichs informacji */ ?>'; file_put_contents($id . '.php', $content); include($id . '.php'); http://www.php.net/unlink($id . '.php'); ?>
~wrzasq a może zamiast pisać posty w odpowiedzi na coś co Ci się uroiło napisz odpowiedź na to co zostało powiedziane
Nikt nie twierdzi, że w PHP można meta programować, bo to oczywista nieprawda.
Podane przykłady to przykłady gdzie takie lub podobne zachowanie jest zaledwie symulowane. Przecież w żadnym z powyższych postów nikt nie twierdzi (poza głupią wikipedią, ale ją olewamy), że to jest meta programowanie.
Pozwolicie drodzy koledzy, że włączę się w tą dyskusję. Najpierw jednak chciałbym Was prosić o wyjaśnienie co rozumiecie pod pojęciem metaprogramowanie. Pytam ponieważ śmiem się nie zgadzać z opinią, że takie coś nie istnieje, ale być może cała rzecz rozchodziłaby się o rozumienie tego pojęcia.
Pozdrawiam,
Łukasz
No ja właśnie nie mam pojęcia co to jest, ale z definicji podanej przez radex'a
mam wrażenie że metaprogramowaniem jest na przykład cache pakietu smarty,
który generuje wykonywalny kod PHP ze swoich tagów.
edit>
Chociaż z drugiej strony wydaje mi się to ostro naciągane po przeczytaniu wstępu z http://www.php.net/manual/pl/intro.runkit.php
IMHO Metaprogramowanie jest to uzupełnianie aplikacji "dodatkowymi funkcjonalnościami" już w czasie jej działania. Np. mechanizm active record pobiera z bazy danych informacje o polach w tabeli i na ich podstawie tworzy findery.
Z tego co zauważyłem, nie do końca wszyscy się zgadzają na temat tego co to jest meta-programowanie. Zacznę możne, wiec od przedstawienia mojego rozumowania tego terminu.
Otóż, metaprogramming bierze się z słowa metadata. Wg. wikipedia, metadata to jest "data about data" czyli dane opisujące czym są jakieś dane. Najprostszym przykładem (możne nie tak oczywistym) jest tabela danych w bazie danych. Faktyczne dane są zapisywane w tej tabeli w wierszach i kolumnach, ale dodatkowo dla kazdej tabeli jest opisywane kodowanie znaków, silnik obsługujący te dane, informacje te tak naprawdę w żaden logiczny sposób nie są powiązane z faktycznymi danymi, bo np. jaki się nazywa tabela, jakie jest kodowanie znaków tak naprawdę z logicznego punktu widzenia nie ma nic wspólnego z nazwa użytkownika, z nazwa/ilością produktów itd... ale informacje te są niezbędne do działania systemy gdyż, np. pozwalają dobrać odpowiedni algorytm sortowania, czy np. bez informacji o silniku obsługiwania tej tabeli nie jesteśmy w stanie obsłużyć tych danych.
Metaprogramowanie imo, jest to dodawanie dodatkowych informacji o już istniejących strukturach danych, blokach kodu, klasach i/lub innych obiektach (nie chodzi mi o znaczenia tego słowa z perspektywy programowania obiektowego). Przekładając to na programowanie obiektowe (bo nie spotkałem się z pojęciem metaprogramowania w przypadku programowania strukturalnego), jest to dodawanie nowej funkcjonalności, badz tez "wstrzykiwania" jej do już istniejącego kodu bez ingerencji w sama jego strukturę czy tez ciało. ta nowa funkcjonalność to przede wszystkim informacje o przeznaczeniu oraz sposobie obsługi tej klasy/interfejsu itd... tak jak to się ma do tabeli w bazie danych; rodzaj kodowania czy silnik w żaden sposób nie ingerują w sama tabele (mam na myśli to ze nie zmieniają już istniejące dane) ale pomocne są w sytuacji gdy te dane muszą być obsłużone.
Osobiście uważam ze metaprogramowanie (dodawanie metadanych do obiektów języka) nie jest osiągalna w 100% tak jak to ma miejsce w językach które maja ta charakterystykę wbudowana w siebie. Przykładem którym się posłużę tutaj jako język obsługujący metadane jest C#. Tam metadane są ucieleśniane poprzez Atrybuty. Atrybuty w języku C# są to klasy którymi można oznaczyć inne klasy i tak naprawdę one są czytane tylko w przypadku kiedy oznaczane klasy sa czytane przez inna część systemu. W większości przypadków jest tak ze te atrybuty oznaczają takie rzeczy jak czy dana klasa jest serializowalna itd...
Dam może obszerniejszy przykład stosowania atrybutów w C# i na tym przykładzie pokaże czemu w PHP jest to nieosiągalne. Tworząc nowy web service w C# (WCF) robimy tak:
<?php $dynamicPHP = ''; for ($i = 0; $i<100; ++$i) { $dynamicPHP .= "echo \"Właśnie wypisuję $i\n\";\n"; } http://www.php.net/eval($dynamicPHP); ?>
Przepraszam, że nie przeczytałem wszystkiego, ale ilość tekstu mnie po prostu odstraszyła
Proszę o skorygowanie mojego rozumowania...
Jeśli dobrze zrozumiałem to metaprogramowanie zachodzi wtedy, kiedy generuję treść i edytuję inną w tym samym skrypcie?
Coś zbyt banalne jak dla mnie.
@MajareQ
Skoro wszytko jest tak proste dla Ciebie, to przeczytaj temat, to aż jedna strona.
Sedziwoj, nie zrozumiałeś chyba mojej prośby.
Prosiłem tylko o odpowiedzenia na pytanie.
Myślę, że to dla średnio wykształconego programisty nie jest trudne, nieprawdaż?
Z tego co rozumie to metaprogramowanie to pisanie programów poprzez programy. Więc każdy język skryptowy jest metaprogramowalny, java jest metaprogramowalna a także C# jest metaprowalny ... i pewnie wiele innych.
Nie rozumiem natomiast czemu się tak upierać, że PHP nie jest metaprogramowalne.
Zanim zaczniemy się kłócić proszę o podanie jakiś namiarów na prace, które traktują o tym temacie i na podstawie których twierdzicie, że jest tak a nie inaczej.
Sam także postaram się coś znaleźć na ten temat.
pozdrawiam,
Łukasz
@MajareQ tu poczytaj.
http://wazniak.mimuw.edu.pl/index.php?title=Zaawansowane_CPP/Wyk%C5%82ad_8:_Metaprogramowanie
prostym przykładem może być utworzenie pliku zapis do jakiegoś echo i później zaincludowanie tego pliku. ( kiedyś ktoś taki przykład na forum napisał ).
@ 2 powyższe posty - Proszę nie robić offtopów
@Cysiaczek
Ok, już nie będę (nie zwracaj uwagi na 3 poniższe zdania )
@Systemy operacyjne w Javie
Takie systemy istnieją, działają i wcale nie piszą ich nienormalni ludzie. Oczywiście należy się zgodzić z tym, że jedne języki są lepsze do określonych zastosowań inne gorsze, ale nie należy wprowadzać żadnego językowego faszyzmu. Przetwarzanie formularza na stronie da się zrobić nawet z poziomu Pascala – wystarczy tylko umieć.
// Widzę że nie bardzo do Ciebie dociera to co się piszę. Może ostrzeżenie Cię czegoś nauczy.
// ~webdice
PHP Jak najbardziej pozwala na metaprogramowanie, podobnie jak każdy inny język który nie wymaga kompilacji plików źródłowych do poprawnego ich działania (tak sądzę, nie znam wszystkich tych języków).
Za "program" w PHP można uznać zbiór skryptów stanowiących jedną aplikację, która może (o czym wszyscy doskonale wiemy) zamieniać sama swoje pliki źródłowe. Często spotyka się aplikacje które przechowują dane (jak np. ustawienia) w swoich plikach źródłowych, będących podstawowymi plikami aplikacji. Aplikacje te umożliwiają zamianę tych danych w trakcie działania aplikacji (może się to odbywać bez ingerencji programisty).
Późno już jest więc może nie do końca zrozumiałem definicję metaprogramowania, pisze co myślę.
Nie wiem czy dobrze zrozumiałem dość obszerny post nasty to to co jest miedzy nawiasami [] jest tylko opisem komentarzem. Na podstawie którego jest powiedzmy (tak jak w przykladzie powiedział) generowany plik WSDL czyli to powinno być zaliczane do meta programowania jeśli ja na postawie kawałka kodu oraz jego komentarza wygeneruje plik wymagany do jakiegoś działania, w tym wypadku tekże niech to będzie WSDL
<?php class Obj { /** * * @return int */ public function pobierzLicznik() { //jakis tam kod } } ?>
http://pl.wikipedia.org/wiki/Metaprogramowanie
Metaprogramowanie - jest techniką która umożliwia programom tworzenie lub modyfikację kodu innych programów (lub ich samych).
Tak więc oczywistym jest że PHP daj takie możliwości , np: tworzenie kodu JavaScript
pobieramy nazwy grafik z folderu i dajemy je do pętli generującej zmienne js dla galerii js.
@Spawnm
Nie do końca o ten sens chodzi w tym temacie, chodzi o generowanie kody PHP przez PHP na podstawie jakiś metadanych. (taki ja sens tego widzę) Czyli robienie wiele nie robiąc dużo.
Jeśli pod pojęciem metaprogramowanie rozumiemy "uzupełnianie" lub "wzbogacanie" kodu aplikacji już podczas wykonywania tego kodu to w php jest to jaknajbardziej możliwe. Służą do tego takie funkcje jak np. [b]create_function[/b] czy eval, a także Reflection API. Z mojego punktu widzenia metody magiczne takie jak __get, __set czy __call to też metaprogramowanie gdyż umożliwiają obsłużenie przez programistę przypadków, których nie może on z góry przewidzeć (uzależnionych np. od struktury danych), lub ma zwyczajnie ochotę na implementację mechanizmów uniwersalnych.
Rezultaty tego metaprogramowania mogą zostać "utracone" w chwili wykonania kodu lub też zapisane do późniejszego wykożystania. Przy pomocy PHP możemy wygenerować nowe fragmenty kodu a nawet przedefiniować już zdefiniowane przez nas klasy czy funkcje. Dla mnie jest to już metaprogramowanie. Możemy dyskutować, który język jest bardziej predystynowany do tego aby nazywać go królem metaprogramowania, ale chyba nie o ranking w tym wątku chodzi.
Jako ciekawostka, dzięki funkcjom lambda, od PHP5.3 będzie możliwe rozszerzanie klas o nowe metody - na żywo.
<?php class Object { private http://www.php.net/static $methods = http://www.php.net/array(); public http://www.php.net/static function extend($name, $method) { if (is_callable($method)) { self::$methods[$name] = $method; } } public function __call($method, $arguments) { if (http://www.php.net/isset(self::$methods[$method])) { http://www.php.net/array_unshift($arguments, $this); return call_user_func_array(self::$methods[$method], $arguments); } else { throw new Exception('Unknown method '.$method.' called.'); } } public http://www.php.net/static function __callStatic($method, $arguments) { if (http://www.php.net/isset(self::$methods[$method])) { http://www.php.net/array_unshift($arguments, get_called_class()); return call_user_func_array(self::$methods[$method], $arguments); } else { throw new Exception('Unknown method '.$method.' called.'); } } } ?>
<?php class Foo extends Object { } $method = function($one, $two) { return $one + $two; }; Foo::extend('add', $method); http://www.php.net/echo Foo::add(2, 2); // 4 ?>
Wzbogacanie klas o dodatkowe metody jest od dawna możliwe i bez funkcji lambda http://www.garfieldtech.com/blog/php-magic-call
<?php http://www.php.net/defined(COS) or http://www.php.net/die('nie mozna uruchomic bezposrednio'); ?>
Prawdą jest, że porządny hosting udostępnia katalog co najmniej o poziom wyżej public_html, ale jeśli nawet tak nie jest to można sobie poradzić używając podkatalogu z odpowiednim .htaccess - em. Pisanie w każdym pliku czegoś na kształt:
<?php http://www.php.net/defined(COS) or http://www.php.net/die('nie mozna uruchomic bezposrednio'); ?>
Nie chcę specjalne marudzić, ale czy temat nie tyczy się czasem Metaprogramowania a nie zastosowań przestrzeni nazw wraz z rozwiązaniami nowego PHP?
Metaprogramowanie, to... dziwna rzecz. Wydaje mi się, że mniej więcej łapię założenia jakie kierują metaprogramowaniem. Umyka mi za to trochę sens takich rozwiązań... Nie potrafię sobie wyobrazić sytuacji w której użycie metapr. byłoby conajmniej wskazane (i optymalne). Generowanie kodu który w niedalekiej przyszłości miałby zostać wykonany to (wybaczcie, widocznie nie mam aż tak wielkiej wyobraźni) przerost formy nad treścią. Chyba, że ten temat jest czysto teoretyczny i pomija pytanie "po co?" na rzecz "czy da się?" bo nie sądzę, żeby skrypt sam był w stanie uzupełnić sie o newralgiczne elementy. Hmm, ORM?
I tak mnie właśnie coś ruszyło... Czy rozwiązanie Zend Framework odnośnie klas tablic objętych relacją i wywołań właściwie nieistniejących metod finderów podpada pod Metaprogramowanie? Chodzi mi o wywołanie metody:
<?php $tabela = new MojaTabela(); $wynik = $tabela->findParentImieByNazwisko('Kowalski'); ?>
Nie wiem czy to już metaprogramowanie czy tylko generowanie kodu, ale ja używam do tego Apache Velocity, które mi generuje klasy PHP. Skrypt wygląda w uproszczeniu tak:
class virgo${tr.FV($entity.name)} extends JTable { var $${entity.prefix}_id = null; #foreach( $property in $entity.properties ) var $${entity.prefix}_${tr.f_v($property.name)} = null; #end ...
Metaprogramowanie. Temat na tyle obszerny i dla mnie mało znany że sam nie wiem czy dobrze go rozumie ale chciał bym o coś zapytać.
Otóż swego czasu poszedłem sobie na spore ułatwienie. Otóż pisałem mappery do dość obszernej bazy danych i miało to troszkę potrwać. Dopóki nie wpadłem na mały pomysł. Otóż dopisałem po prostu kod PHP który zwyczajnie w wypadku braku obiektu danych dla mappera bazy danych łączy się z bazą, pobiera informacje o tabeli do której odnosi się mapper (lub tabel, kwestia co mapper dokładnie robi ale takich co odnoszą się do +1 tabeli mam mało) i... tworzy klasę obiektu danych dla tej tabeli i zapisuje do pliku. Taki plik jest później po prostu includowany przez system.
Podobnie jest z mapperami ale tu zaoszczędza mi to tylko połowę pracy. Bo czasami mapper potrzebuje specyficzną metodę tylko dla siebie. Jednak i tak mam oszczędzone żmudne klepanie.
W każdym razie PHP wychodzi na przeciw naszym potrzebą. Mój system nie tylko potrafi sobie wygenerować obiekt danych jeżeli nikt go nie zapewni na podstawie bazy danych ale tez i na podstawie mappera (który ma bazę translacji gdzie wewnętrzna zmienna bądź tablica ma info co powinno się przyporządkować jakiemu atrybutowi obiektu danych). Osiągnąłem to w dość prosty sposób (choć jak pierwotnie o tym pomyślałem to wydawało mi się to niemożliwe).
Użyłem token_get_all();. Funkcja ta jest w stanie wczytać z pliku kod PHP, rozbić go na czynniki pierwsze i zaserwować nam tablicę. Używając token_name() identyfikuję cyferki na nazwy i łatwo wyłapuje elementy składni. Ich lista znajduje się tutaj: http://www.php.net/manual/en/tokens.php
W skrócie. PHP jest w stanie W PEŁNI zanalizować kod PHP a co dalej zrobicie to Wasza sprawa. Pamiętajcie tylko by zachować to na specjalne przypadki bo nie są to operacje lekkie. Sam umieściłem takie rozwiązanie tylko w paru drobnych miejscach jak właśnie przy mapperach. W razie gdy nie chce mi się tworzyć obiektów danych bądź też po prostu zapomniałem o tym, system sam zaopiekuje się tym problemem jeżeli odnajdzie mappera bądź tabelę w bazie danych.
I taka ciekawostka dla Was. Swego czasu napisałem małe narzędzie które odchudziło mi kod PHP. Powyższym sposobem wyciąłem WSZYSTKIE białe znaki (co najlepsze nie potrzeba wyrażeń regularnych, ciągi znaków w "" i '' są oznaczone w tablicy jako string, reszta jako elementy składni więc nie można wyciąć białych znaków np z komunikatów przypadkiem), komentarze itp. Po instrukcjach wstawiłem spację (żeby nie dostać classDatabase tylko class Database) no i upewniłem się że po -> nie ma spacji ( $obiekt->include() to nie to samo co $obiekt -> include() ) a całą resztę zostawiłem w spokoju. Pozbyłem się też komentarzy.
Wyszło na to że 31% mojego kodu w systemie to spacje, tabulatory i komentarze. Ponieważ rozmiar plików zmniejszył się do 69%. W każdym razie PHP potrafi o siebie zadbać :-)
W każdym razie to pytanie:
Czy gdy system sam się potrafi odchudzić (wywołując sobie odchudzanie na nowych plikach, dorabianie sobie obiektów danych w razie czego itp), uzupełnić itp wg wytycznych (listę tego co usunąć np umieszczam w phpdoc nad metodą która to robi. PHP jest w stanie również dobrać się od tych komentarzy. A ktoś czytając kod klasy jest w stanie powiedzieć co ona wywali. Mało tego, modyfikując komentarz modyfikuje zachowanie klasy.) itp to możemy tutaj mówić o metaprogramowaniu ?
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)