Metaprogramowanie
Metaprogramowanie to technika, która umożliwia programom tworzenie lub modyfikację kodu innych programów. Program, który wykonuje takie operacje, nazywamy metaprogramem. Dzięki metaprogramowaniu możliwa jest dynamiczna modyfikacja kodu podczas kompilacji oraz w czasie jego wykonania. Języki programowania, takie jak JavaScript, C#, Lisp, Perl, PHP, Python, Ruby, Groovy i inne, wspierają te możliwości.
Przykłady metaprogramów
Oto kilka prostych przykładów metaprogramów:
- Bash:
#!/bin/bash echo '#!/bin/bash' >program for ((I=1; I<=992; I++)) do echo "echo $I" >>program done chmod +x program
Ten skrypt generuje plik zawierający 993 linie kodu, które wypisują liczby od 1 do 992.
- Python:
from os import system clay = open("adam.py", "w") clay.write("print("Madam, I'm Adam.")") clay.close() system("python3.0 adam.py")
Program tworzy plik „adam.py”, który po uruchomieniu wypisuje „Madam, I’m Adam.”.
- Scheme:
(define adam "adam.scm") (define clay (open-output-file adam)) (display "(display " clay) (write "Madam, I'm Adam." clay) (display ")" clay) (close-output-port clay) (load adam)
Makra w języku Lisp
W dialektach języka Lisp, takich jak Scheme i Clojure, występują makra składniowe, które umożliwiają dynamiczne modyfikowanie kodu. Przykład makra when w Scheme:
(define-macro (when cond . body)
`(if ,cond
(begin
,@body)))
W Clojure makro wygląda następująco:
(defmacro when [test & body]
(list 'if test (cons 'do body)))
Introspekcja i Refleksja
Introspekcja i refleksja to cechy metaprogramowania, które pozwalają na analizowanie obiektów w pamięci, takie jak lista pól i metod w obiekcie czy dynamiczne wywoływanie metod na podstawie wygenerowanego kodu.
Magiczne metody
W językach takich jak JavaScript, Python czy PHP istnieje mechanizm magicznych metod, który pozwala na zastąpienie wbudowanych funkcji przez własne implementacje. Przykłady to __call
i __get
w PHP, które aktywują się przy próbie wywołania nieistniejącej metody lub pobrania właściwości. W JavaScript mechanizm ten jest realizowany przez symbole i obiekty Proxy, wprowadzone w wersji ES6.