poniedziałek, 30 kwietnia 2007

Metaprogramming

Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data or that do part of the work during compile time that is otherwise done at run time. In many cases, this allows programmers to get more done in the same amount of time as they would take to write all the code manually.
-wikipedia

Mówią że C++ daje narzędzia do metaprogrammingu a java nie. Przykładowo by wygenerować klasę całkują funkcje zwracającą double i std::complex, starczy napisać jeden szablon integrator.

Ale to Java ma powera do metaprogrammingu. Czytałem sobie w "Thinking in Java"* w rozdziale o adnotacjach, adnotacje to są takie fajne metadane dołaczane do kodu źródłowego. Ogólnie można do każdego elementu klasy dopisać jakąś informację. Co więcej, można za pomocą narzędzia apt (annotation processing tool), generować nowe pliki klas.

Dziś pisałem sejwowanie klasy do XML wygląda tak że na początku pisze się kod:
Element root = new Element ("[nazwa klasy]");
a dla każdej składowej klasy pisze się:
Element [nazwa składowej] = new Element ("[nazwa składowej]");
[nazwa_składowej].appendChild(String.valueOf(this.[nazwa_składowej]));
root.appendChild([nazwa_składowej]);
W sumie upierdliwe jak się ma 9 składowych. Wyglądało to tak:

package jb.sk;

import java.io.Serializable;
import java.text.ParseException;

import nu.xom.Element;

public class Comment implements Serializable, Comparable{

private static final long serialVersionUID = -5532948060127766412L;

String author;
String authorEmail;
long authorIP;
String authorUrl;
long date;
boolean deleted;
String message;
CommentId no = null;
boolean visible;
public Element getXML(){

Element comment = new Element("comment");

Element author = new Element("author");
author.appendChild(getAuthor());
comment.appendChild(author);

Element authorEmail = new Element("authorEmail");
authorEmail.appendChild(getAuthorEmail());
comment.appendChild(authorEmail);

Element authorIP = new Element("authorIP");
authorIP.appendChild(String.valueOf(getAuthorIP()));
comment.appendChild(authorIP);

Element authorUrl = new Element("authorUrl");
authorUrl.appendChild(getAuthorUrl());
comment.appendChild(authorUrl);

Element date = new Element("date");
date.appendChild(String.valueOf(getDate()));
comment.appendChild(date);

Element deleted = new Element("this.deleted");
date.appendChild(String.valueOf(isDeleted()));
comment.appendChild(deleted);

Element message = new Element("message");
message.appendChild(getMessage());
comment.appendChild(message);

Element no = new Element("no");
no.appendChild(this.no.toString());
comment.appendChild(no);

Element visible = new Element("visible");
visible.appendChild(String.valueOf(isVisible()));
comment.appendChild(visible);

return comment;
}
/*...*/
}


No i trafiło mnie żestarczyłoby utworzyć takie coś:
@XMLAble
abstract Comment_base{
@XMLAbleElement
String author;
/*..*/
Comment(Element e){
set(e);
}

abstract Element getXML();
abstract set(Element elem);

/*..*/
}


Potem automatycznie (przy pomocy apta) pisać klasę: Comment, która te dwie metody nadpisuje kodem generowanym w trywialny sposób. Po prostu tworzyłaby nową klasę dla @XMLAble i która sejwowałaby każdy element z annotacją @XMLAbleElement. Trywial :). Może kiedyś napisze coś takiego :).


---
* Wersji IV, wersja III dostępna na stronie autora (nie ma w niej chyba rozdziału w którym mówie).

Reklama:

Zachęcam do zajrzenia na: http://fizolof.blogspot.com/

Moja strona domowa zmieniła adres: http://jbhome.wikidot.com/

Ta strona nie będzie już updejtowana. Blog został przeniesiony na: http://jbhome.wikidot.com/blog:start

Blog: