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:
Kod
[ServiceContract(
Name = "CalculatorService",
Namespace = "http://microsoft.wcf.documentation",
CallbackContract = typeof(IHelloCallbackContract),
SessionMode = SessionMode.Required
)]
public interface ICalculator
{
[OperationContractAttribute(IsOneWay=true)]
void Add(double n1, double n2);
[OperationContract(ProtectionLevel=ProtectionLevel.EncryptAndSign)]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
public class CalculatorService : ICalculator
{
public void Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
}
public double Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Multiply(double n1, double n2)
{
double result = n1 * n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Divide(double n1, double n2)
{
double result = n1 / n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
}
Jak widzimy w tym przykładzie, ta klasa działa w 100% bez załączonych atrybutów (to co jest miedzy [ ]) ale te dodatkowe dane pozwalają na wygenerowanie WSDL tej usługi oraz pozwala usługom hostingowym na doczytanie się dodatkowych informacji niezbędnych do eksponowania tej klasy jako usługę. (jakbym usuną jakiś atrybut OperationContract z powiedzmy metody "multiply" to hostowana usługa by była o ta jedna operacje mniejsza).
To co w php nie jest osiągalne to jest parsowanie tych komentarzy i przekładanie ich na już utworzone obiekty/enumeracje (php nie zna enumeracji

). Aby moc takowa funkcjonalność zaimplementować w PHP trzeba by było zrobić coś co by parsowało te komentarze i moglo to przekładać na "żywe" obiekty z kodu takie jak klasy, enumeracje itd...
mam na myśli obsługę coś w stylu:
Kod
CallbackContract = typeof(IHelloCallbackContract),
SessionMode = SessionMode.Required
bo to:
Kod
Name = "CalculatorService",
Namespace = "http://microsoft.wcf.documentation"
jest jak najbardziej osiagalne w PHP.
Trochę się rozpisałem tak może i bez sensu bo to wszystko jest w necie, ale liczę na to ze ktoś skomentuje to co napisałem i wywiąże sie z tego ciekawa dyskusja
Czekam i Pozdrawiam